00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00025 #include <iostream>
00026 #include <stdexcept>
00027 #include <sstream>
00028 #include <cstdio>
00029 #include <sys/wait.h>
00030 #include <iomanip>
00031 #include "Makefile.h"
00032 #include "test_util.h"
00033
00034 #include <boost/iostreams/stream.hpp>
00035 #include <boost/iostreams/device/file_descriptor.hpp>
00036 #include <boost/iostreams/code_converter.hpp>
00037
00038 using namespace makefile;
00039 namespace fs = boost::filesystem;
00040 namespace io = boost::iostreams;
00041
00042 namespace makefile { namespace tester {
00050 int exec_make(std::stringbuf& makeoutbuf, std::stringbuf& makeerrbuf)
00051 {
00052
00053 int fdmakein[2];
00054 int fdmakeout[2];
00055 int fdmakeerr[2];
00056 if(pipe(fdmakein) || pipe(fdmakeout) || pipe(fdmakeerr))
00057 {
00058 std::cerr << "pipe() failed." << std::endl;
00059 return false;
00060 }
00061
00062
00063 if(fork())
00064 {
00065 close(fdmakein[0]);
00066 close(fdmakeout[1]);
00067 close(fdmakeerr[1]);
00068
00069
00070
00071 #ifdef USE_WCHAR
00072 io::stream< io::code_converter<io::file_descriptor_sink> > makein(fdmakein[1]);
00073 #else
00074 io::stream<io::file_descriptor_sink> makein(fdmakein[1]);
00075 #endif
00076 io::stream<io::file_descriptor_source> makeout(fdmakeout[0]);
00077 io::stream<io::file_descriptor_source> makeerr(fdmakeerr[0]);
00078
00079
00080 Makefile::getSingleton().writeMakefile(makein);
00081 Makefile::getSingleton().clean();
00082 makein.close();
00083
00084 makeout.get(makeoutbuf, '\0');
00085 makeerr.get(makeerrbuf, '\0');
00086
00087 int status;
00088 wait(&status);
00089 if(WIFEXITED(status))
00090 {
00091 return WEXITSTATUS(status);
00092 }
00093
00094 std::cerr << "Command terminated abnormally. status=" << std::hex << status << std::endl;
00095 return status;
00096
00097
00098 } else {
00099 close(fdmakein[1]);
00100 close(fdmakeout[0]);
00101 close(fdmakeerr[0]);
00102
00103 if(dup2(fdmakein[0], 0) == -1 || dup2(fdmakeout[1], 1) == -1 || dup2(fdmakeerr[1], 2) == -1)
00104 {
00105 std::cerr << "Failed to switch std stream" << std::endl;
00106 exit(-1);
00107 }
00108
00109
00110 const char* const argv[] = {"make", "-f-", (char*) NULL};
00111 execvp(argv[0], (char* const*)argv);
00112 return -1;
00113 }
00114 }
00115
00116 bool Test::run()
00117 {
00118 int status = exec_make(makeoutbuf, makeerrbuf);
00119
00120 std::cout << std::setw(30) << std::left << name;
00121 if(eval())
00122 {
00123 std::cout << "PASS" << std::endl;
00124 return true;
00125 }
00126 std::cout << "FAIL" << std::endl;
00127 std::cout << "ret: " << status << std::endl;
00128 std::cout << "out: " << makeoutbuf.str() << std::endl;
00129 std::cout << "cmp: " << goodout << std::endl;
00130 std::cout << "err: " << makeerrbuf.str() << std::endl;
00131 return false;
00132 }
00133 }}