test_util_win32.cpp

Go to the documentation of this file.
00001 /*
00002 This file is part of hugin.
00003 
00004 hugin is free software: you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation, either version 2 of the License, or
00007 (at your option) any later version.
00008 
00009 hugin is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with hugin.  If not, see <http://www.gnu.org/licenses/>.
00016 */
00017 
00026 #include <iostream>
00027 #include <stdexcept>
00028 #include <sstream>
00029 #include <cstdio>
00030 #include <iomanip>
00031 #include "Makefile.h"
00032 #include "test_util.h"
00033 
00034 #include <windows.h>
00035 #include <tchar.h>
00036 
00037 #define BOOST_IOSTREAMS_USE_DEPRECATED
00038 #include <boost/iostreams/stream.hpp>
00039 #include <boost/iostreams/device/file_descriptor.hpp>
00040 #include <boost/iostreams/code_converter.hpp>
00041 
00042 using namespace makefile;
00043 namespace fs = boost::filesystem;
00044 namespace io = boost::iostreams;
00045 
00046 namespace makefile { namespace tester {
00056 int exec_make(std::stringbuf& makeoutbuf, std::stringbuf& makeerrbuf)
00057 {
00058         // store 2 HANDLE per pipe {read, write}
00059         HANDLE hmakein_rd = NULL;
00060         HANDLE hmakein_wr = NULL;
00061         HANDLE hmakeout_rd = NULL;
00062         HANDLE hmakeout_wr = NULL;
00063         HANDLE hmakeerr_rd = NULL;
00064         HANDLE hmakeerr_wr = NULL;
00065 
00066         // this is taken from an example in msdn
00067         SECURITY_ATTRIBUTES sa;
00068         sa.nLength = sizeof(SECURITY_ATTRIBUTES); // seems that windows doesn't know it's own structs ;)
00069         sa.bInheritHandle = true;
00070         sa.lpSecurityDescriptor = NULL;
00071 
00072         if( !CreatePipe(&hmakeout_rd, &hmakeout_wr, &sa, 0) ||  // create pipes  
00073                 !CreatePipe(&hmakein_rd, &hmakein_wr, &sa, 0) ||
00074                 !CreatePipe(&hmakeerr_rd, &hmakeerr_wr, &sa, 0) ||
00075                 !SetHandleInformation(hmakeout_rd, HANDLE_FLAG_INHERIT, 0) || // and set inheritance handle information
00076                 !SetHandleInformation(hmakein_wr, HANDLE_FLAG_INHERIT, 0) ||
00077                 !SetHandleInformation(hmakeerr_rd, HANDLE_FLAG_INHERIT, 0))
00078         {
00079                 std::cerr << "CreatePipe() failed." << std::endl;
00080                 return -1;
00081         }
00082 
00083 
00084         // parent creates child
00085         PROCESS_INFORMATION pi; 
00086         STARTUPINFO si;
00087          
00088         // Set up members of the PROCESS_INFORMATION structure. 
00089  
00090         ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) );
00091  
00092         // Set up members of the STARTUPINFO structure. 
00093         // This structure specifies the STDIN and STDOUT handles for redirection.
00094  
00095         ZeroMemory( &si, sizeof(STARTUPINFO) );
00096         si.cb = sizeof(STARTUPINFO); 
00097         si.hStdError = hmakeerr_wr;
00098         si.hStdOutput = hmakeout_wr;
00099         si.hStdInput = hmakein_rd;
00100         si.dwFlags |= STARTF_USESTDHANDLES;
00101  
00102         // Create the child process. 
00103     
00104         if( !CreateProcess(NULL, 
00105         "make -f-",     // command line
00106         NULL,          // process security attributes 
00107         NULL,          // primary thread security attributes 
00108         TRUE,          // handles are inherited 
00109         0,             // creation flags 
00110         NULL,          // use parent's environment 
00111         NULL,          // use parent's current directory 
00112         &si,  // STARTUPINFO pointer 
00113         &pi))  // receives PROCESS_INFORMATION 
00114         {
00115                 std::cerr << "CreateProcess failed" << std::endl;
00116                 return -1;
00117         }
00118         // Important, close unused pipe ends.
00119         CloseHandle(hmakeout_wr);
00120         CloseHandle(hmakeerr_wr);
00121         CloseHandle(hmakein_rd);
00122 
00123                 
00124                 // boost gives us a way to use those pipes in C++ style.
00125                 // the code_converter allows wchar mode Makefile to be written to a char-pipe
00126 #ifdef USE_WCHAR
00127         io::stream< io::code_converter<io::file_descriptor_sink> > makein(fdmakein[1]);
00128 #else
00129         io::stream<io::file_descriptor_sink> makein(hmakein_wr);
00130 #endif
00131         io::stream<io::file_descriptor_source> makeout(hmakeout_rd);
00132         io::stream<io::file_descriptor_source> makeerr(hmakeerr_rd);
00133 
00134         // Write the makefile to make's stdin
00135         Makefile::getSingleton().writeMakefile(makein);
00136         Makefile::getSingleton().clean();
00137         makein.close();
00138 
00139         makeout.get(makeoutbuf, '\0');  // delimiter \0 should read until eof.
00140         makeerr.get(makeerrbuf, '\0');
00141 
00142         WaitForSingleObject(pi.hProcess, INFINITE);
00143         DWORD status;
00144         GetExitCodeProcess(pi.hProcess, &status);
00145         return status;
00146 }
00147 
00148 bool Test::run()
00149 {
00150         int status = exec_make(makeoutbuf, makeerrbuf);
00151 
00152         std::cout << std::setw(30) << std::left <<  name;
00153         if(eval())
00154         {
00155                 std::cout << "PASS" << std::endl;
00156                 return true;
00157         }
00158         std::cout << "FAIL" << std::endl;
00159         std::cout << "ret: " << status << std::endl;
00160         std::cout << "out: " << makeoutbuf.str() << std::endl;
00161         std::cout << "cmp: " << goodout << std::endl;
00162         std::cout << "err: " << makeerrbuf.str() << std::endl;
00163         return false;
00164 }
00165 }}

Generated on Wed Sep 17 01:25:38 2014 for Hugintrunk by  doxygen 1.3.9.1