private function generateAnswer($vArray) { if ($vArray['substitute_attr']['val'] == "ans") { //We're substituting ONLY the answer. There is no need to recompile the program $vToReturn = $this->substitutePercentages($vArray['substitute']); if (strstr($vToReturn, ";") == false) { $vToReturn = "return " . $vToReturn . ";"; } return eval($vToReturn); } //Ok. Looks like we're going to have to recompile the program with some new values. This could get interesting. //Due to the way this shitty XML parser works, we have to do some basic checks. If there's more than one "substitute" key in the answer // the parser puts it into an array, otherwise it doesn't $vToProcess = array(); if (is_array($vArray['substitute'])) { for ($i = 0; $i < sizeof($vArray['substitute']) / 2; $i++) { $vToProcess[] = array("attr" => $vArray['substitute'][$i . "_attr"]['val'], "code" => $vArray['substitute'][$i]); } } else { $vToProcess[] = array("attr" => $vArray['substitute_attr']['val'], "code" => $vArray['substitute']); } //OK. So now we do a whole NEW set of substitutions for this fake answer. //We'll start by copying over the REAL substitutions and replacing them as we go with fake ones //From here on in, this function will look a lot like populateSubstitutions $this->mSubstitutions_tmp = $this->mSubstitutions; foreach ($vToProcess as $vTP) { $toGen = $vTP['code']; if (strstr($toGen, ";") == false) { //Assuming its just a function without ; and return $toGen = "return " . $toGen . ";"; } $toGen = $this->substitutePercentages($toGen); //echo "TOGEN: " . $toGen; $this->mSubstitutions_tmp[$vTP['attr']] = eval($toGen); } //Ok. All the new 'fake' substitutions are done. Time to generate the entire new 'fake' problem! $this->mProblem_tmp = $this->mFileContents['question']['problem']; //Replace what needs to be replaced foreach ($this->mSubstitutions_tmp as $mSubKey => $mSub) { $this->mProblem_tmp = str_replace("`" . $mSubKey . "`", $mSub, $this->mProblem_tmp); } //Now compile this fake problem into a fake solution and return the output return Model_Shell_Compiler::compileAndReturn(rand(1, 99999) . "_fake", $this->mProblem_tmp); }
/** * C++ Specific Compilation * * @param string $mTempFolder * @param string $vFilePrefix * @param string $mSource * @return string * @author Ben Evans */ protected static function cpp_compile_and_return($mTempFolder, $vFilePrefix, $mSource) { if (in_array(strtolower(PHP_OS), explode(",", self::NIX_OSES))) { // Linux, Mac etc if (file_exists(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".cpp"))) { unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".cpp")); } if (file_exists(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix))) { unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix)); } $fh = fopen(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".cpp"), 'w'); fwrite($fh, $mSource); fclose($fh); $toExec = "g++ \"" . $mTempFolder . "/" . $vFilePrefix . ".cpp\" -o \"" . $mTempFolder . "/" . $vFilePrefix . "\""; //echo "EXECUTING: " . $toExec; $execResult = exec($toExec); die; //Now make sure it compiled if (file_exists("{$mTempFolder}/" . $vFilePrefix)) { $toExec = "timeout 5 \"" . $mTempFolder . "/" . $vFilePrefix . "\" > \"" . $mTempFolder . "/" . $vFilePrefix . ".txt\""; //echo "EXECUTING: " . $toExec; exec($toExec); $vContents = file_get_contents("{$mTempFolder}/" . $vFilePrefix . ".txt"); //Delete all the stuff we made unlink("{$mTempFolder}/" . $vFilePrefix . ".cpp"); unlink("{$mTempFolder}/" . $vFilePrefix); unlink("{$mTempFolder}/" . $vFilePrefix . ".txt"); return $vContents; } else { return "Compilation failed! Reason:" . $execResult; } } else { //We're running Windows (probably) if (file_exists("{$mTempFolder}/" . $vFilePrefix . ".cpp")) { unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".cpp")); } if (file_exists("{$mTempFolder}/" . $vFilePrefix . ".exe")) { unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".exe")); } $fh = fopen(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".cpp"), 'w'); fwrite($fh, $mSource); fclose($fh); $toExec = "C:\\mingw\\bin\\g++.exe \"" . $mTempFolder . "\\" . $vFilePrefix . ".cpp\" -o \"" . $mTempFolder . "\\" . $vFilePrefix . ".exe\" "; echo $toExec; $execResult = exec($toExec); if (file_exists("{$mTempFolder}/" . $vFilePrefix . ".exe")) { $toExec = "\"" . $mTempFolder . "\\" . $vFilePrefix . ".exe\" > \"" . $mTempFolder . "\\" . $vFilePrefix . ".txt\""; $fh = fopen("{$mTempFolder}/" . $vFilePrefix . ".bat", 'w'); fwrite($fh, $toExec); fclose($fh); $toExec = '"' . $mTempFolder . "\\limitexec.exe\" 5 " . $vFilePrefix; //echo "EXECUTING: " . $toExec; exec($toExec); $vContents = file_get_contents(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".txt")); //Delete all the stuff we made unlink("{$mTempFolder}/" . $vFilePrefix . ".cpp"); unlink("{$mTempFolder}/" . $vFilePrefix . ".bat"); unlink("{$mTempFolder}/" . $vFilePrefix . ".exe"); unlink("{$mTempFolder}/" . $vFilePrefix . ".txt"); return $vContents; } else { return "Compilation failed! Reason:" . $execResult; } } //End Windows-specific code }