<commit_before>/*
 * copyright (c) 2017 Matthew Oliver
 *
 * This file is part of ShiftMediaProject.
 *
 * ShiftMediaProject is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * ShiftMediaProject 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with ShiftMediaProject; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "projectGenerator.h"

#include <algorithm>
#include <utility>

bool ProjectGenerator::runCompiler(const vector<string> & vIncludeDirs, map<string, vector<string>> &mDirectoryObjects, int iRunType)
{
#ifdef _MSC_VER
    //If compiled by msvc then only msvc builds are supported
    return runMSVC(vIncludeDirs, mDirectoryObjects, iRunType);
#else
    //Otherwise only gcc and mingw are supported
    return runGCC(vIncludeDirs, mDirectoryObjects, iRunType);
#endif
}

bool ProjectGenerator::runMSVC(const vector<string> & vIncludeDirs, map<string, vector<string>> &mDirectoryObjects, int iRunType)
{
    //Create a test file to read in definitions
    string sOutDir = m_ConfigHelper.m_sOutDirectory;
    makeFileGeneratorRelative(sOutDir, sOutDir);
    string sCLExtra = "/I\"" + sOutDir + "include/\"";
    for (StaticList::const_iterator vitIt = vIncludeDirs.cbegin(); vitIt < vIncludeDirs.cend(); vitIt++) {
        string sIncludeDir = *vitIt;
        uint uiFindPos2 = sIncludeDir.find("$(OutDir)");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 9, sOutDir);
        }
        uiFindPos2 = sIncludeDir.find("$(");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 2, "%");
        }
        uiFindPos2 = sIncludeDir.find(")");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 1, "%");
        }
        sCLExtra += " /I\"" + sIncludeDir + '\"';
    }
    string sTempFolder = sTempDirectory + m_sProjectName;

    //Use Microsoft compiler to pass the test file and retrieve declarations
    string sCLLaunchBat = "@echo off\n";
    sCLLaunchBat += "if exist \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat\" ( \n\
call \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat\" >NUL 2>NUL \n\
goto MSVCVarsDone \n\
) else if exist \"%VS140COMNTOOLS%\\vsvars32.bat\" ( \n\
call \"%VS140COMNTOOLS%\\vsvars32.bat\" \n\
goto MSVCVarsDone \n\
) else if exist \"%VS120COMNTOOLS%\\vsvars32.bat\" ( \n\
call \"%VS120COMNTOOLS%\\vsvars32.bat\" \n\
goto MSVCVarsDone \n\
) else if exist \"%VS110COMNTOOLS%\\vsvars32.bat\" ( \n\
call \"%VS110COMNTOOLS%\\vsvars32.bat\" \n\
goto MSVCVarsDone \n\
) else ( \n\
echo fatal error : An installed version of Visual Studio could not be detected. \n\
exit /b 1 \n\
) \n\
:MSVCVarsDone \n";
    sCLLaunchBat += "mkdir \"" + sTempDirectory + "\" > nul 2>&1\n";
    sCLLaunchBat += "mkdir \"" + sTempFolder + "\" > nul 2>&1\n";
    for (map<string, StaticList>::iterator itI = mDirectoryObjects.begin(); itI != mDirectoryObjects.end(); itI++) {
        const uint uiRowSize = 32;
        uint uiNumCLCalls = (uint)ceilf((float)itI->second.size() / (float)uiRowSize);
        uint uiTotalPos = 0;
        string sDirName = sTempFolder + "/" + itI->first;
        if (itI->first.length() > 0) {
            //Need to make output directory so compile doesn't fail outputting
            sCLLaunchBat += "mkdir \"" + sDirName + "\" > nul 2>&1\n";
        }
        string sRuntype;
        //Check type of compiler call
        if (iRunType == 0) {
            sRuntype = "/FR\"" + sDirName + "/\"" + " /Fo\"" + sDirName + "/\"";
        } else if (iRunType == 1) {
            sRuntype = "/EP /P";
        }

        //Split calls into groups of 50 to prevent batch file length limit
        for (uint uiI = 0; uiI < uiNumCLCalls; uiI++) {
            sCLLaunchBat += "cl.exe";
            sCLLaunchBat += " /I\"" + m_ConfigHelper.m_sRootDirectory + "\" /I\"" + m_ConfigHelper.m_sProjectDirectory + "\" " + sCLExtra + " /D\"_DEBUG\" /D\"WIN32\" /D\"_WINDOWS\" /D\"HAVE_AV_CONFIG_H\" /D\"inline=__inline\" /FI\"compat.h\" " + sRuntype + " /c /MP /w /nologo";
            uint uiStartPos = uiTotalPos;
            for (uiTotalPos; uiTotalPos < min(uiStartPos + uiRowSize, itI->second.size()); uiTotalPos++) {
                if (iRunType == 0) {
                    makeFileGeneratorRelative(itI->second[uiTotalPos], itI->second[uiTotalPos]);
                }
                sCLLaunchBat += " \"" + itI->second[uiTotalPos] + "\"";
            }
            sCLLaunchBat += " > log.txt 2>&1\nif %errorlevel% neq 0 goto exitFail\n";
        }
        if (iRunType == 1) {
            sCLLaunchBat += "move *.i " + sDirName + "/ >nul 2>&1\n";
        }
    }
    if (iRunType == 0) {
        sCLLaunchBat += "del /F /S /Q *.obj >nul 2>&1\n";
    }
    sCLLaunchBat += "del log.txt >nul 2>&1\n";
    sCLLaunchBat += "exit /b 0\n:exitFail\n";
    if (iRunType == 1) {
        sCLLaunchBat += "del /F /S /Q *.i >nul 2>&1\n";
    }
    sCLLaunchBat += "rmdir /S /Q " + sTempDirectory + "\nexit /b 1";
    if (!writeToFile("test.bat", sCLLaunchBat)) {
        return false;
    }

    if (0 != system("test.bat")) {
        outputError("Errors detected during test compilation :-");
        string sTestOutput;
        if (loadFromFile("log.txt", sTestOutput)) {
            //Output errors from log.txt
            bool bError = false;
            bool bMissingVS = false;
            bool bMissingDeps = false;
            uint uiFindPos = sTestOutput.find(" error ");
            while (uiFindPos != string::npos) {
                //find end of line
                uint uiFindPos2 = sTestOutput.find_first_of("\n(", uiFindPos + 1);
                string sTemp = sTestOutput.substr(uiFindPos + 1, uiFindPos2 - uiFindPos - 1);
                outputError(sTemp, false);
                uiFindPos = sTestOutput.find(" error ", uiFindPos2 + 1);
                //Check what type of error was found
                if (!bMissingDeps && (sTemp.find("open include file") != string::npos)) {
                    bMissingDeps = true;
                } else if (!bMissingVS && (sTemp.find("Visual Studio could not be detected") != string::npos)) {
                    bMissingVS = true;
                } else {
                    bError = true;
                }
            }
            uiFindPos = sTestOutput.find("internal or external command");
            if (uiFindPos != string::npos) {
                uint uiFindPos2 = sTestOutput.find('\n', uiFindPos + 1);
                uiFindPos = sTestOutput.rfind('\n', uiFindPos);
                uiFindPos = (uiFindPos == string::npos) ? 0 : uiFindPos;
                outputError(sTestOutput.substr(uiFindPos, uiFindPos2 - uiFindPos), false);
                bMissingVS = true;
            }
            if (bMissingVS) {
                outputError("Based on the above error(s) Visual Studio is not installed correctly on the host system.", false);
                outputError("Install a compatible version of Visual Studio before trying again.", false);
                deleteFile("log.txt");
            } else if (bMissingDeps) {
                outputError("Based on the above error(s) there are files required for dependency libraries that are not available", false);
                outputError("Ensure that any required dependencies are available in 'OutDir' based on the supplied configuration options before trying again.", false);
                outputError("Consult the supplied readme for instructions for installing varying dependencies.", false);
                outputError("If a dependency has been cloned from a ShiftMediaProject repository then ensure it has been successfully built before trying again.", false);
                outputError("  Removing the offending configuration option can also be used to remove the error.", false);
                deleteFile("log.txt");
            } else if (bError) {
                outputError("Unknown error detected. See log.txt for further details.", false);
            }
        }
        //Remove the test header files
        deleteFile("test.bat");
        deleteFolder(sTempDirectory);
        return false;
    }

    //Remove the compilation objects
    deleteFile("test.bat");
    return true;
}

bool ProjectGenerator::runGCC(const vector<string> & vIncludeDirs, map<string, vector<string>> &mDirectoryObjects, int iRunType)
{
    //Create a test file to read in definitions
    string sOutDir = m_ConfigHelper.m_sOutDirectory;
    makeFileGeneratorRelative(sOutDir, sOutDir);
    string sCLExtra = "-I\"" + sOutDir + "include/\"";
    for (StaticList::const_iterator vitIt = vIncludeDirs.cbegin(); vitIt < vIncludeDirs.cend(); vitIt++) {
        string sIncludeDir = *vitIt;
        uint uiFindPos2 = sIncludeDir.find("$(OutDir)");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 9, sOutDir);
        }
        uiFindPos2 = sIncludeDir.find("$(");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 2, "$");
        }
        uiFindPos2 = sIncludeDir.find(")");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.erase(uiFindPos2, 1);
        }
        sCLExtra += " -I\"" + sIncludeDir + '\"';
    }
    string sTempFolder = sTempDirectory + m_sProjectName;

    //Use GNU compiler to pass the test file and retrieve declarations
    string sCLLaunchBat = "#!/bin/bash\n";
    sCLLaunchBat += "exitFail() {\n";
    if (iRunType == 1) {
        sCLLaunchBat += "rm -rf *.i > /dev/null 2>&1\n";
    }
    sCLLaunchBat += "rm -rf " + sTempDirectory + " > /dev/null 2>&1\nexit 1\n}\n";
    sCLLaunchBat += "mkdir \"" + sTempDirectory + "\" > /dev/null 2>&1\n";
    sCLLaunchBat += "mkdir \"" + sTempFolder + "\" > /dev/null 2>&1\n";
    for (map<string, StaticList>::iterator itI = mDirectoryObjects.begin(); itI != mDirectoryObjects.end(); itI++) {
        string sDirName = sTempFolder + "/" + itI->first;
        if (itI->first.length() > 0) {
            //Need to make output directory so compile doesn't fail outputting
            sCLLaunchBat += "mkdir \"" + sDirName + "\" > /dev/null 2>&1\n";
        }
        string sRuntype;
        //Check type of compiler call
        if (iRunType == 0) {
            outputError("Generation of definitions is not supported using gcc.");
            return false;
        } else if (iRunType == 1) {
            sRuntype = "-E -P";
        }
        //Check if gcc or mingw
        if (m_ConfigHelper.m_sToolchain.find("mingw") != string::npos) {
            sCLExtra += "-D\"WIN32\" -D\"_WINDOWS\"";
        }

        //Split calls as gcc outputs a single file at a time
        for (StaticList::iterator vitJ = itI->second.begin(); vitJ < itI->second.end(); vitJ++) {
            sCLLaunchBat += "gcc";
            sCLLaunchBat += " -I\"" + m_ConfigHelper.m_sRootDirectory + "\" -I\"" + m_ConfigHelper.m_sProjectDirectory + "\" " + sCLExtra + " -D_DEBUG " + sRuntype + " -c -w";
            if (iRunType == 0) {
                makeFileGeneratorRelative(*vitJ, *vitJ);
            }
            sCLLaunchBat += " \"" + *vitJ + "\"";
            if (iRunType == 0) {
                sCLLaunchBat += " -o " + *vitJ + ".o";
            } else if (iRunType == 1) {
                sCLLaunchBat += " -o " + *vitJ + ".i";
            }
            sCLLaunchBat += " > log.txt 2>&1\nif (( $? )); then\nexitFail\nfi\n";
        }
    }
    if (iRunType == 0) {
        sCLLaunchBat += "rm -rf *.o > /dev/null 2>&1\n";
    }
    sCLLaunchBat += "rm log.txt > /dev/null 2>&1\n";
    sCLLaunchBat += "exit 0\n";
    if (!writeToFile("test.sh", sCLLaunchBat)) {
        return false;
    }
    if (0 != system("test.sh")) {
        outputError("Errors detected during test compilation :-");
        outputError("Unknown error detected. See log.txt for further details.", false);
        //Remove the test header files
        deleteFile("test.sh");
        deleteFolder(sTempDirectory);
        return false;
    }

    //Remove the compilation objects
    deleteFile("test.sh");
    return true;
}<commit_msg>Correctly handle cases of include directories including the cwd during test compilation.<commit_after>/*
 * copyright (c) 2017 Matthew Oliver
 *
 * This file is part of ShiftMediaProject.
 *
 * ShiftMediaProject is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * ShiftMediaProject 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with ShiftMediaProject; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "projectGenerator.h"

#include <algorithm>
#include <utility>

bool ProjectGenerator::runCompiler(const vector<string> & vIncludeDirs, map<string, vector<string>> &mDirectoryObjects, int iRunType)
{
#ifdef _MSC_VER
    //If compiled by msvc then only msvc builds are supported
    return runMSVC(vIncludeDirs, mDirectoryObjects, iRunType);
#else
    //Otherwise only gcc and mingw are supported
    return runGCC(vIncludeDirs, mDirectoryObjects, iRunType);
#endif
}

bool ProjectGenerator::runMSVC(const vector<string> & vIncludeDirs, map<string, vector<string>> &mDirectoryObjects, int iRunType)
{
    //Create a test file to read in definitions
    string sOutDir = m_ConfigHelper.m_sOutDirectory;
    makeFileGeneratorRelative(sOutDir, sOutDir);
    vector<string> vIncludeDirs2 = vIncludeDirs;
    vIncludeDirs2.insert(vIncludeDirs2.begin(), sOutDir + "include/");
    vIncludeDirs2.insert(vIncludeDirs2.begin(), m_ConfigHelper.m_sProjectDirectory);
    vIncludeDirs2.insert(vIncludeDirs2.begin(), m_ConfigHelper.m_sRootDirectory);
    string sCLExtra;
    for (StaticList::const_iterator vitIt = vIncludeDirs2.cbegin(); vitIt < vIncludeDirs2.cend(); vitIt++) {
        string sIncludeDir = *vitIt;
        uint uiFindPos2 = sIncludeDir.find("$(OutDir)");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 9, sOutDir);
        }
        uiFindPos2 = sIncludeDir.find("$(");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 2, "%");
        }
        uiFindPos2 = sIncludeDir.find(")");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 1, "%");
        }
        if (sIncludeDir.length() == 0) {
            sIncludeDir = "./";
        } else if (sIncludeDir.find_first_of("./%") != 0) {
            sIncludeDir = "./" + sIncludeDir;
        }
        sCLExtra += " /I\"" + sIncludeDir + '\"';
    }
    string sTempFolder = sTempDirectory + m_sProjectName;

    //Use Microsoft compiler to pass the test file and retrieve declarations
    string sCLLaunchBat = "@echo off\n";
    sCLLaunchBat += "if exist \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat\" ( \n\
call \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat\" >NUL 2>NUL \n\
goto MSVCVarsDone \n\
) else if exist \"%VS140COMNTOOLS%\\vsvars32.bat\" ( \n\
call \"%VS140COMNTOOLS%\\vsvars32.bat\" \n\
goto MSVCVarsDone \n\
) else if exist \"%VS120COMNTOOLS%\\vsvars32.bat\" ( \n\
call \"%VS120COMNTOOLS%\\vsvars32.bat\" \n\
goto MSVCVarsDone \n\
) else if exist \"%VS110COMNTOOLS%\\vsvars32.bat\" ( \n\
call \"%VS110COMNTOOLS%\\vsvars32.bat\" \n\
goto MSVCVarsDone \n\
) else ( \n\
echo fatal error : An installed version of Visual Studio could not be detected. \n\
exit /b 1 \n\
) \n\
:MSVCVarsDone \n";
    sCLLaunchBat += "mkdir \"" + sTempDirectory + "\" > nul 2>&1\n";
    sCLLaunchBat += "mkdir \"" + sTempFolder + "\" > nul 2>&1\n";
    for (map<string, StaticList>::iterator itI = mDirectoryObjects.begin(); itI != mDirectoryObjects.end(); itI++) {
        const uint uiRowSize = 32;
        uint uiNumCLCalls = (uint)ceilf((float)itI->second.size() / (float)uiRowSize);
        uint uiTotalPos = 0;
        string sDirName = sTempFolder + "/" + itI->first;
        if (itI->first.length() > 0) {
            //Need to make output directory so compile doesn't fail outputting
            sCLLaunchBat += "mkdir \"" + sDirName + "\" > nul 2>&1\n";
        }
        string sRuntype;
        //Check type of compiler call
        if (iRunType == 0) {
            sRuntype = "/FR\"" + sDirName + "/\"" + " /Fo\"" + sDirName + "/\"";
        } else if (iRunType == 1) {
            sRuntype = "/EP /P";
        }

        //Split calls into groups of 50 to prevent batch file length limit
        for (uint uiI = 0; uiI < uiNumCLCalls; uiI++) {
            sCLLaunchBat += "cl.exe ";
            sCLLaunchBat += sCLExtra + " /D\"_DEBUG\" /D\"WIN32\" /D\"_WINDOWS\" /D\"HAVE_AV_CONFIG_H\" /D\"inline=__inline\" /FI\"compat.h\" " + sRuntype + " /c /MP /w /nologo";
            uint uiStartPos = uiTotalPos;
            for (uiTotalPos; uiTotalPos < min(uiStartPos + uiRowSize, itI->second.size()); uiTotalPos++) {
                if (iRunType == 0) {
                    makeFileGeneratorRelative(itI->second[uiTotalPos], itI->second[uiTotalPos]);
                }
                sCLLaunchBat += " \"" + itI->second[uiTotalPos] + "\"";
            }
            sCLLaunchBat += " > ffvs_log.txt 2>&1\nif %errorlevel% neq 0 goto exitFail\n";
        }
        if (iRunType == 1) {
            sCLLaunchBat += "move *.i " + sDirName + "/ >nul 2>&1\n";
        }
    }
    if (iRunType == 0) {
        sCLLaunchBat += "del /F /S /Q *.obj >nul 2>&1\n";
    }
    sCLLaunchBat += "del ffvs_log.txt >nul 2>&1\n";
    sCLLaunchBat += "exit /b 0\n:exitFail\n";
    if (iRunType == 1) {
        sCLLaunchBat += "del /F /S /Q *.i >nul 2>&1\n";
    }
    sCLLaunchBat += "rmdir /S /Q " + sTempDirectory + "\nexit /b 1";
    if (!writeToFile("ffvs_compile.bat", sCLLaunchBat)) {
        return false;
    }

    if (0 != system("ffvs_compile.bat")) {
        outputError("Errors detected during compilation :-");
        string sTestOutput;
        if (loadFromFile("ffvs_log.txt", sTestOutput)) {
            //Output errors from ffvs_log.txt
            bool bError = false;
            bool bMissingVS = false;
            bool bMissingDeps = false;
            uint uiFindPos = sTestOutput.find(" error ");
            while (uiFindPos != string::npos) {
                //find end of line
                uint uiFindPos2 = sTestOutput.find_first_of("\n(", uiFindPos + 1);
                string sTemp = sTestOutput.substr(uiFindPos + 1, uiFindPos2 - uiFindPos - 1);
                outputError(sTemp, false);
                uiFindPos = sTestOutput.find(" error ", uiFindPos2 + 1);
                //Check what type of error was found
                if (!bMissingDeps && (sTemp.find("open include file") != string::npos)) {
                    bMissingDeps = true;
                } else if (!bMissingVS && (sTemp.find("Visual Studio could not be detected") != string::npos)) {
                    bMissingVS = true;
                } else {
                    bError = true;
                }
            }
            uiFindPos = sTestOutput.find("internal or external command");
            if (uiFindPos != string::npos) {
                uint uiFindPos2 = sTestOutput.find('\n', uiFindPos + 1);
                uiFindPos = sTestOutput.rfind('\n', uiFindPos);
                uiFindPos = (uiFindPos == string::npos) ? 0 : uiFindPos;
                outputError(sTestOutput.substr(uiFindPos, uiFindPos2 - uiFindPos), false);
                bMissingVS = true;
            }
            if (bMissingVS) {
                outputError("Based on the above error(s) Visual Studio is not installed correctly on the host system.", false);
                outputError("Install a compatible version of Visual Studio before trying again.", false);
                deleteFile("ffvs_log.txt");
            } else if (bMissingDeps) {
                outputError("Based on the above error(s) there are files required for dependency libraries that are not available", false);
                outputError("Ensure that any required dependencies are available in 'OutDir' based on the supplied configuration options before trying again.", false);
                outputError("Consult the supplied readme for instructions for installing varying dependencies.", false);
                outputError("If a dependency has been cloned from a ShiftMediaProject repository then ensure it has been successfully built before trying again.", false);
                outputError("  Removing the offending configuration option can also be used to remove the error.", false);
                deleteFile("ffvs_log.txt");
            } else if (bError) {
                outputError("Unknown error detected. See ffvs_log.txt for further details.", false);
            }
        }
        //Remove the compile files
        deleteFile("ffvs_compile.bat");
        deleteFolder(sTempDirectory);
        return false;
    }

    //Remove the compilation objects
    deleteFile("ffvs_compile.bat");
    return true;
}

bool ProjectGenerator::runGCC(const vector<string> & vIncludeDirs, map<string, vector<string>> &mDirectoryObjects, int iRunType)
{
    //Create a test file to read in definitions
    string sOutDir = m_ConfigHelper.m_sOutDirectory;
    makeFileGeneratorRelative(sOutDir, sOutDir);
    vector<string> vIncludeDirs2 = vIncludeDirs;
    vIncludeDirs2.insert(vIncludeDirs2.begin(), sOutDir + "include/");
    vIncludeDirs2.insert(vIncludeDirs2.begin(), m_ConfigHelper.m_sProjectDirectory);
    vIncludeDirs2.insert(vIncludeDirs2.begin(), m_ConfigHelper.m_sRootDirectory);
    string sCLExtra;
    for (StaticList::const_iterator vitIt = vIncludeDirs2.cbegin(); vitIt < vIncludeDirs2.cend(); vitIt++) {
        string sIncludeDir = *vitIt;
        uint uiFindPos2 = sIncludeDir.find("$(OutDir)");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 9, sOutDir);
        }
        uiFindPos2 = sIncludeDir.find("$(");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 2, "%");
        }
        uiFindPos2 = sIncludeDir.find(")");
        if (uiFindPos2 != string::npos) {
            sIncludeDir.replace(uiFindPos2, 1, "%");
        }
        if (sIncludeDir.length() == 0) {
            sIncludeDir = "./";
        } else if (sIncludeDir.find_first_of("./%") != 0) {
            sIncludeDir = "./" + sIncludeDir;
        }
        sCLExtra += " /I\"" + sIncludeDir + '\"';
    }
    string sTempFolder = sTempDirectory + m_sProjectName;

    //Use GNU compiler to pass the test file and retrieve declarations
    string sCLLaunchBat = "#!/bin/bash\n";
    sCLLaunchBat += "exitFail() {\n";
    if (iRunType == 1) {
        sCLLaunchBat += "rm -rf *.i > /dev/null 2>&1\n";
    }
    sCLLaunchBat += "rm -rf " + sTempDirectory + " > /dev/null 2>&1\nexit 1\n}\n";
    sCLLaunchBat += "mkdir \"" + sTempDirectory + "\" > /dev/null 2>&1\n";
    sCLLaunchBat += "mkdir \"" + sTempFolder + "\" > /dev/null 2>&1\n";
    for (map<string, StaticList>::iterator itI = mDirectoryObjects.begin(); itI != mDirectoryObjects.end(); itI++) {
        string sDirName = sTempFolder + "/" + itI->first;
        if (itI->first.length() > 0) {
            //Need to make output directory so compile doesn't fail outputting
            sCLLaunchBat += "mkdir \"" + sDirName + "\" > /dev/null 2>&1\n";
        }
        string sRuntype;
        //Check type of compiler call
        if (iRunType == 0) {
            outputError("Generation of definitions is not supported using gcc.");
            return false;
        } else if (iRunType == 1) {
            sRuntype = "-E -P";
        }
        //Check if gcc or mingw
        if (m_ConfigHelper.m_sToolchain.find("mingw") != string::npos) {
            sCLExtra += "-D\"WIN32\" -D\"_WINDOWS\"";
        }

        //Split calls as gcc outputs a single file at a time
        for (StaticList::iterator vitJ = itI->second.begin(); vitJ < itI->second.end(); vitJ++) {
            sCLLaunchBat += "gcc ";
            sCLLaunchBat += sCLExtra + " -D_DEBUG " + sRuntype + " -c -w";
            if (iRunType == 0) {
                makeFileGeneratorRelative(*vitJ, *vitJ);
            }
            sCLLaunchBat += " \"" + *vitJ + "\"";
            if (iRunType == 0) {
                sCLLaunchBat += " -o " + *vitJ + ".o";
            } else if (iRunType == 1) {
                sCLLaunchBat += " -o " + *vitJ + ".i";
            }
            sCLLaunchBat += " > ffvs_log.txt 2>&1\nif (( $? )); then\nexitFail\nfi\n";
        }
    }
    if (iRunType == 0) {
        sCLLaunchBat += "rm -rf *.o > /dev/null 2>&1\n";
    }
    sCLLaunchBat += "rm ffvs_log.txt > /dev/null 2>&1\n";
    sCLLaunchBat += "exit 0\n";
    if (!writeToFile("ffvs_compile.sh", sCLLaunchBat)) {
        return false;
    }
    if (0 != system("ffvs_compile.sh")) {
        outputError("Errors detected during compilation :-");
        outputError("Unknown error detected. See ffvs_log.txt for further details.", false);
        //Remove the compilation files
        deleteFile("ffvs_compile.sh");
        deleteFolder(sTempDirectory);
        return false;
    }

    //Remove the compilation objects
    deleteFile("ffvs_compile.sh");
    return true;
}<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "GeoTagController.h"
#include "QGCQFileDialog.h"
#include "QGCLoggingCategory.h"
#include "MainWindow.h"
#include <math.h>
#include <QtEndian>
#include <QMessageBox>
#include <QDebug>
#include <cfloat>

#include "ExifParser.h"
#include "ULogParser.h"
#include "PX4LogParser.h"

GeoTagController::GeoTagController(void)
    : _progress(0)
    , _inProgress(false)
{
    connect(&_worker, &GeoTagWorker::progressChanged,   this, &GeoTagController::_workerProgressChanged);
    connect(&_worker, &GeoTagWorker::error,             this, &GeoTagController::_workerError);
    connect(&_worker, &GeoTagWorker::started,           this, &GeoTagController::inProgressChanged);
    connect(&_worker, &GeoTagWorker::finished,          this, &GeoTagController::inProgressChanged);
}

GeoTagController::~GeoTagController()
{

}

void GeoTagController::pickLogFile(void)
{
    QString filename = QGCQFileDialog::getOpenFileName(MainWindow::instance(), tr("Select log file load"), QString(), tr("ULog file (*.ulg);;PX4 log file (*.px4log);;All Files (*.*)"));
    if (!filename.isEmpty()) {
        _worker.setLogFile(filename);
        emit logFileChanged(filename);
    }
}

void GeoTagController::pickImageDirectory(void)
{
    QString dir = QGCQFileDialog::getExistingDirectory(MainWindow::instance(), tr("Select image directory"));
    if (!dir.isEmpty()) {
        _worker.setImageDirectory(dir);
        emit imageDirectoryChanged(dir);
    }
}

void GeoTagController::pickSaveDirectory(void)
{
    QString dir = QGCQFileDialog::getExistingDirectory(MainWindow::instance(), tr("Select save directory"));
    if (!dir.isEmpty()) {
        _worker.setSaveDirectory(dir);
        emit saveDirectoryChanged(dir);
    }
}

void GeoTagController::startTagging(void)
{
    _errorMessage.clear();
    emit errorMessageChanged(_errorMessage);

    QDir imageDirectory = QDir(_worker.imageDirectory());
    if(!imageDirectory.exists()) {
        _setErrorMessage(tr("Cannot find the image directory"));
        return;
    }
    if(_worker.saveDirectory() == "") {
        if(!imageDirectory.mkdir(_worker.imageDirectory() + "/TAGGED")) {
            QMessageBox msgBox(QMessageBox::Question,
                               tr("Images have alreay been tagged."),
                               tr("The images have already been tagged. Do you want to replace the previously tagged images?"),
                               QMessageBox::Cancel);
            msgBox.setWindowModality(Qt::ApplicationModal);
            msgBox.addButton(tr("Replace"), QMessageBox::ActionRole);
            if (msgBox.exec() == QMessageBox::Cancel) {
                _setErrorMessage(tr("Images have already been tagged"));
                return;
            }
            QDir oldTaggedFolder = QDir(_worker.imageDirectory() + "/TAGGED");
            oldTaggedFolder.removeRecursively();
            if(!imageDirectory.mkdir(_worker.imageDirectory() + "/TAGGED")) {
                _setErrorMessage(tr("Couldn't replace the previously tagged images"));
                return;
            }
        }
    } else {
        QDir saveDirectory = QDir(_worker.saveDirectory());
        if(!saveDirectory.exists()) {
            _setErrorMessage(tr("Cannot find the save directory"));
            return;
        }
        saveDirectory.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable);
        QStringList nameFilters;
        nameFilters << "*.jpg" << "*.JPG";
        saveDirectory.setNameFilters(nameFilters);
        QStringList imageList = saveDirectory.entryList();
        if(!imageList.isEmpty()) {
            QMessageBox msgBox(QMessageBox::Question,
                               tr("Save folder not empty."),
                               tr("The save folder already contains images. Do you want to replace them?"),
                               QMessageBox::Cancel);
            msgBox.setWindowModality(Qt::ApplicationModal);
            msgBox.addButton(tr("Replace"), QMessageBox::ActionRole);
            if (msgBox.exec() == QMessageBox::Cancel) {
                _setErrorMessage(tr("Save folder not empty"));
                return;
            }
            foreach(QString dirFile, imageList)
            {
                if(!saveDirectory.remove(dirFile)) {
                    _setErrorMessage(tr("Couldn't replace the existing images"));
                    return;
                }
            }
        }
    }
    _worker.start();
}

void GeoTagController::_workerProgressChanged(double progress)
{
    _progress = progress;
    emit progressChanged(progress);
}

void GeoTagController::_workerError(QString errorMessage)
{
    _errorMessage = errorMessage;
    emit errorMessageChanged(errorMessage);
}

void GeoTagController::_setErrorMessage(const QString& error)
{
    _errorMessage = error;
    emit errorMessageChanged(error);
}

GeoTagWorker::GeoTagWorker(void)
    : _cancel(false)
    , _logFile("")
    , _imageDirectory("")
    , _saveDirectory("")
{

}

void GeoTagWorker::run(void)
{
    _cancel = false;
    emit progressChanged(1);
    double nSteps = 5;

    // Load Images
    _imageList.clear();
    QDir imageDirectory = QDir(_imageDirectory);
    imageDirectory.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable);
    imageDirectory.setSorting(QDir::Name);
    QStringList nameFilters;
    nameFilters << "*.jpg" << "*.JPG";
    imageDirectory.setNameFilters(nameFilters);
    _imageList = imageDirectory.entryInfoList();
    if(_imageList.isEmpty()) {
        emit error(tr("The image directory doesn't contain images, make sure your images are of the JPG format"));
        return;
    }
    emit progressChanged((100/nSteps));

    // Parse EXIF
    ExifParser exifParser;
    _imageTime.clear();
    for (int i = 0; i < _imageList.size(); ++i) {
        QFile file(_imageList.at(i).absoluteFilePath());
        if (!file.open(QIODevice::ReadOnly)) {
            emit error(tr("Geotagging failed. Couldn't open an image."));
            return;
        }
        QByteArray imageBuffer = file.readAll();
        file.close();

        _imageTime.append(exifParser.readTime(imageBuffer));

        emit progressChanged((100/nSteps) + ((100/nSteps) / _imageList.size())*i);

        if (_cancel) {
            qCDebug(GeotaggingLog) << "Tagging cancelled";
            emit error(tr("Tagging cancelled"));
            return;
        }
    }

    // Load log
    bool isULog = _logFile.endsWith(".ulg", Qt::CaseSensitive);
    QFile file(_logFile);
    if (!file.open(QIODevice::ReadOnly)) {
        emit error(tr("Geotagging failed. Couldn't open log file."));
        return;
    }
    QByteArray log = file.readAll();
    file.close();

    // Instantiate appropriate parser
    _triggerList.clear();
    bool parseComplete = false;
    QString errorString;
    if (isULog) {
        ULogParser parser;
        parseComplete = parser.getTagsFromLog(log, _triggerList, errorString);

    } else {
        PX4LogParser parser;
        parseComplete = parser.getTagsFromLog(log, _triggerList);

    }

    if (!parseComplete) {
        if (_cancel) {
            qCDebug(GeotaggingLog) << "Tagging cancelled";
            emit error(tr("Tagging cancelled"));
            return;
        } else {
            qCDebug(GeotaggingLog) << "Log parsing failed";
            errorString = tr("%1 - tagging cancelled").arg(errorString.isEmpty() ? tr("Log parsing failed") : errorString);
            emit error(errorString);
            return;
        }
    }
    emit progressChanged(3*(100/nSteps));

    qCDebug(GeotaggingLog) << "Found " << _triggerList.count() << " trigger logs.";

    if (_cancel) {
        qCDebug(GeotaggingLog) << "Tagging cancelled";
        emit error(tr("Tagging cancelled"));
        return;
    }

    // Filter Trigger
    if (!triggerFiltering()) {
        qCDebug(GeotaggingLog) << "Geotagging failed in trigger filtering";
        emit error(tr("Geotagging failed in trigger filtering"));
        return;
    }
    emit progressChanged(4*(100/nSteps));

    if (_cancel) {
        qCDebug(GeotaggingLog) << "Tagging cancelled";
        emit error(tr("Tagging cancelled"));
        return;
    }

    // Tag images
    int maxIndex = std::min(_imageIndices.count(), _triggerIndices.count());
    maxIndex = std::min(maxIndex, _imageList.count());
    for(int i = 0; i < maxIndex; i++) {
        int imageIndex = _imageIndices[i];
        if (imageIndex >= _imageList.count()) {
            emit error(tr("Geotagging failed. Image requested not present."));
            return;
        }
        QFile fileRead(_imageList.at(_imageIndices[i]).absoluteFilePath());
        if (!fileRead.open(QIODevice::ReadOnly)) {
            emit error(tr("Geotagging failed. Couldn't open an image."));
            return;
        }
        QByteArray imageBuffer = fileRead.readAll();
        fileRead.close();

        if (!exifParser.write(imageBuffer, _triggerList[_triggerIndices[i]])) {
            emit error(tr("Geotagging failed. Couldn't write to image."));
            return;
        } else {
            QFile fileWrite;
            if(_saveDirectory == "") {
                fileWrite.setFileName(_imageDirectory + "/TAGGED/" + _imageList.at(_imageIndices[i]).fileName());
            } else {
                fileWrite.setFileName(_saveDirectory + "/" + _imageList.at(_imageIndices[i]).fileName());
            }
            if (!fileWrite.open(QFile::WriteOnly)) {
                emit error(tr("Geotagging failed. Couldn't write to an image."));
                return;
            }
            fileWrite.write(imageBuffer);
            fileWrite.close();
        }
        emit progressChanged(4*(100/nSteps) + ((100/nSteps) / maxIndex)*i);

        if (_cancel) {
            qCDebug(GeotaggingLog) << "Tagging cancelled";
            emit error(tr("Tagging cancelled"));
            return;
        }
    }

    if (_cancel) {
        qCDebug(GeotaggingLog) << "Tagging cancelled";
        emit error(tr("Tagging cancelled"));
        return;
    }

    emit progressChanged(100);
}

bool GeoTagWorker::triggerFiltering()
{
    _imageIndices.clear();
    _triggerIndices.clear();

    if(_imageList.count() > _triggerList.count()) {             // Logging dropouts
        qCDebug(GeotaggingLog) << "Detected missing feedback packets.";
    } else if (_imageList.count() < _triggerList.count()) {     // Camera skipped frames
        qCDebug(GeotaggingLog) << "Detected missing image frames.";
    }

    for(int i = 0; i < _imageList.count() && i < _triggerList.count(); i++) {
        _imageIndices.append(_triggerList[i].imageSequence);
        _triggerIndices.append(i);
    }

    return true;
}
<commit_msg>AnalyzeView: Change from foreach to c++11 for<commit_after>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "GeoTagController.h"
#include "QGCQFileDialog.h"
#include "QGCLoggingCategory.h"
#include "MainWindow.h"
#include <math.h>
#include <QtEndian>
#include <QMessageBox>
#include <QDebug>
#include <cfloat>

#include "ExifParser.h"
#include "ULogParser.h"
#include "PX4LogParser.h"

GeoTagController::GeoTagController(void)
    : _progress(0)
    , _inProgress(false)
{
    connect(&_worker, &GeoTagWorker::progressChanged,   this, &GeoTagController::_workerProgressChanged);
    connect(&_worker, &GeoTagWorker::error,             this, &GeoTagController::_workerError);
    connect(&_worker, &GeoTagWorker::started,           this, &GeoTagController::inProgressChanged);
    connect(&_worker, &GeoTagWorker::finished,          this, &GeoTagController::inProgressChanged);
}

GeoTagController::~GeoTagController()
{

}

void GeoTagController::pickLogFile(void)
{
    QString filename = QGCQFileDialog::getOpenFileName(MainWindow::instance(), tr("Select log file load"), QString(), tr("ULog file (*.ulg);;PX4 log file (*.px4log);;All Files (*.*)"));
    if (!filename.isEmpty()) {
        _worker.setLogFile(filename);
        emit logFileChanged(filename);
    }
}

void GeoTagController::pickImageDirectory(void)
{
    QString dir = QGCQFileDialog::getExistingDirectory(MainWindow::instance(), tr("Select image directory"));
    if (!dir.isEmpty()) {
        _worker.setImageDirectory(dir);
        emit imageDirectoryChanged(dir);
    }
}

void GeoTagController::pickSaveDirectory(void)
{
    QString dir = QGCQFileDialog::getExistingDirectory(MainWindow::instance(), tr("Select save directory"));
    if (!dir.isEmpty()) {
        _worker.setSaveDirectory(dir);
        emit saveDirectoryChanged(dir);
    }
}

void GeoTagController::startTagging(void)
{
    _errorMessage.clear();
    emit errorMessageChanged(_errorMessage);

    QDir imageDirectory = QDir(_worker.imageDirectory());
    if(!imageDirectory.exists()) {
        _setErrorMessage(tr("Cannot find the image directory"));
        return;
    }
    if(_worker.saveDirectory() == "") {
        if(!imageDirectory.mkdir(_worker.imageDirectory() + "/TAGGED")) {
            QMessageBox msgBox(QMessageBox::Question,
                               tr("Images have alreay been tagged."),
                               tr("The images have already been tagged. Do you want to replace the previously tagged images?"),
                               QMessageBox::Cancel);
            msgBox.setWindowModality(Qt::ApplicationModal);
            msgBox.addButton(tr("Replace"), QMessageBox::ActionRole);
            if (msgBox.exec() == QMessageBox::Cancel) {
                _setErrorMessage(tr("Images have already been tagged"));
                return;
            }
            QDir oldTaggedFolder = QDir(_worker.imageDirectory() + "/TAGGED");
            oldTaggedFolder.removeRecursively();
            if(!imageDirectory.mkdir(_worker.imageDirectory() + "/TAGGED")) {
                _setErrorMessage(tr("Couldn't replace the previously tagged images"));
                return;
            }
        }
    } else {
        QDir saveDirectory = QDir(_worker.saveDirectory());
        if(!saveDirectory.exists()) {
            _setErrorMessage(tr("Cannot find the save directory"));
            return;
        }
        saveDirectory.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable);
        QStringList nameFilters;
        nameFilters << "*.jpg" << "*.JPG";
        saveDirectory.setNameFilters(nameFilters);
        QStringList imageList = saveDirectory.entryList();
        if(!imageList.isEmpty()) {
            QMessageBox msgBox(QMessageBox::Question,
                               tr("Save folder not empty."),
                               tr("The save folder already contains images. Do you want to replace them?"),
                               QMessageBox::Cancel);
            msgBox.setWindowModality(Qt::ApplicationModal);
            msgBox.addButton(tr("Replace"), QMessageBox::ActionRole);
            if (msgBox.exec() == QMessageBox::Cancel) {
                _setErrorMessage(tr("Save folder not empty"));
                return;
            }
            for(QString dirFile: imageList)
            {
                if(!saveDirectory.remove(dirFile)) {
                    _setErrorMessage(tr("Couldn't replace the existing images"));
                    return;
                }
            }
        }
    }
    _worker.start();
}

void GeoTagController::_workerProgressChanged(double progress)
{
    _progress = progress;
    emit progressChanged(progress);
}

void GeoTagController::_workerError(QString errorMessage)
{
    _errorMessage = errorMessage;
    emit errorMessageChanged(errorMessage);
}

void GeoTagController::_setErrorMessage(const QString& error)
{
    _errorMessage = error;
    emit errorMessageChanged(error);
}

GeoTagWorker::GeoTagWorker(void)
    : _cancel(false)
    , _logFile("")
    , _imageDirectory("")
    , _saveDirectory("")
{

}

void GeoTagWorker::run(void)
{
    _cancel = false;
    emit progressChanged(1);
    double nSteps = 5;

    // Load Images
    _imageList.clear();
    QDir imageDirectory = QDir(_imageDirectory);
    imageDirectory.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable);
    imageDirectory.setSorting(QDir::Name);
    QStringList nameFilters;
    nameFilters << "*.jpg" << "*.JPG";
    imageDirectory.setNameFilters(nameFilters);
    _imageList = imageDirectory.entryInfoList();
    if(_imageList.isEmpty()) {
        emit error(tr("The image directory doesn't contain images, make sure your images are of the JPG format"));
        return;
    }
    emit progressChanged((100/nSteps));

    // Parse EXIF
    ExifParser exifParser;
    _imageTime.clear();
    for (int i = 0; i < _imageList.size(); ++i) {
        QFile file(_imageList.at(i).absoluteFilePath());
        if (!file.open(QIODevice::ReadOnly)) {
            emit error(tr("Geotagging failed. Couldn't open an image."));
            return;
        }
        QByteArray imageBuffer = file.readAll();
        file.close();

        _imageTime.append(exifParser.readTime(imageBuffer));

        emit progressChanged((100/nSteps) + ((100/nSteps) / _imageList.size())*i);

        if (_cancel) {
            qCDebug(GeotaggingLog) << "Tagging cancelled";
            emit error(tr("Tagging cancelled"));
            return;
        }
    }

    // Load log
    bool isULog = _logFile.endsWith(".ulg", Qt::CaseSensitive);
    QFile file(_logFile);
    if (!file.open(QIODevice::ReadOnly)) {
        emit error(tr("Geotagging failed. Couldn't open log file."));
        return;
    }
    QByteArray log = file.readAll();
    file.close();

    // Instantiate appropriate parser
    _triggerList.clear();
    bool parseComplete = false;
    QString errorString;
    if (isULog) {
        ULogParser parser;
        parseComplete = parser.getTagsFromLog(log, _triggerList, errorString);

    } else {
        PX4LogParser parser;
        parseComplete = parser.getTagsFromLog(log, _triggerList);

    }

    if (!parseComplete) {
        if (_cancel) {
            qCDebug(GeotaggingLog) << "Tagging cancelled";
            emit error(tr("Tagging cancelled"));
            return;
        } else {
            qCDebug(GeotaggingLog) << "Log parsing failed";
            errorString = tr("%1 - tagging cancelled").arg(errorString.isEmpty() ? tr("Log parsing failed") : errorString);
            emit error(errorString);
            return;
        }
    }
    emit progressChanged(3*(100/nSteps));

    qCDebug(GeotaggingLog) << "Found " << _triggerList.count() << " trigger logs.";

    if (_cancel) {
        qCDebug(GeotaggingLog) << "Tagging cancelled";
        emit error(tr("Tagging cancelled"));
        return;
    }

    // Filter Trigger
    if (!triggerFiltering()) {
        qCDebug(GeotaggingLog) << "Geotagging failed in trigger filtering";
        emit error(tr("Geotagging failed in trigger filtering"));
        return;
    }
    emit progressChanged(4*(100/nSteps));

    if (_cancel) {
        qCDebug(GeotaggingLog) << "Tagging cancelled";
        emit error(tr("Tagging cancelled"));
        return;
    }

    // Tag images
    int maxIndex = std::min(_imageIndices.count(), _triggerIndices.count());
    maxIndex = std::min(maxIndex, _imageList.count());
    for(int i = 0; i < maxIndex; i++) {
        int imageIndex = _imageIndices[i];
        if (imageIndex >= _imageList.count()) {
            emit error(tr("Geotagging failed. Image requested not present."));
            return;
        }
        QFile fileRead(_imageList.at(_imageIndices[i]).absoluteFilePath());
        if (!fileRead.open(QIODevice::ReadOnly)) {
            emit error(tr("Geotagging failed. Couldn't open an image."));
            return;
        }
        QByteArray imageBuffer = fileRead.readAll();
        fileRead.close();

        if (!exifParser.write(imageBuffer, _triggerList[_triggerIndices[i]])) {
            emit error(tr("Geotagging failed. Couldn't write to image."));
            return;
        } else {
            QFile fileWrite;
            if(_saveDirectory == "") {
                fileWrite.setFileName(_imageDirectory + "/TAGGED/" + _imageList.at(_imageIndices[i]).fileName());
            } else {
                fileWrite.setFileName(_saveDirectory + "/" + _imageList.at(_imageIndices[i]).fileName());
            }
            if (!fileWrite.open(QFile::WriteOnly)) {
                emit error(tr("Geotagging failed. Couldn't write to an image."));
                return;
            }
            fileWrite.write(imageBuffer);
            fileWrite.close();
        }
        emit progressChanged(4*(100/nSteps) + ((100/nSteps) / maxIndex)*i);

        if (_cancel) {
            qCDebug(GeotaggingLog) << "Tagging cancelled";
            emit error(tr("Tagging cancelled"));
            return;
        }
    }

    if (_cancel) {
        qCDebug(GeotaggingLog) << "Tagging cancelled";
        emit error(tr("Tagging cancelled"));
        return;
    }

    emit progressChanged(100);
}

bool GeoTagWorker::triggerFiltering()
{
    _imageIndices.clear();
    _triggerIndices.clear();

    if(_imageList.count() > _triggerList.count()) {             // Logging dropouts
        qCDebug(GeotaggingLog) << "Detected missing feedback packets.";
    } else if (_imageList.count() < _triggerList.count()) {     // Camera skipped frames
        qCDebug(GeotaggingLog) << "Detected missing image frames.";
    }

    for(int i = 0; i < _imageList.count() && i < _triggerList.count(); i++) {
        _imageIndices.append(_triggerList[i].imageSequence);
        _triggerIndices.append(i);
    }

    return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Boulanger Guillaume, Chathura Namalgamuwa
 * The file is distributed under the MIT license
 * The license is available in the LICENSE file or at https://github.com/boulangg/phoenix/blob/master/LICENSE
 */

#include "Kernel.hpp"

#include <stdio.h>
#include <vector>
#include <stdlib.h>
#include <string>
#include <list>
#include <functional>

#include "Console.hpp"

#include <mm/PhysicalAllocator.hpp>
#include <mm/VirtualMapping.hpp>
#include <fs/Elf64.hpp>
#include <fs/KernelFS.hpp>
#include <fs/File.hpp>

#include <lib/Heap.hpp>

class TestElemHeap {
public:
	TestElemHeap(std::string name = ""): indexPrio1(0), prio1(0), indexPrio2(0), prio2(0)
		, name(name) {}

	TestElemHeap(const TestElemHeap& elem): indexPrio1(elem.indexPrio1),
			prio1(elem.prio1), indexPrio2(elem.prio2), prio2(elem.prio2),
			name(elem.name) {
	}

	TestElemHeap& operator=(const TestElemHeap& elem) {
		indexPrio1 = elem.indexPrio1;
		prio1 = elem.prio1;
		indexPrio2 = elem.indexPrio2;
		prio2 = elem.prio2;
		name = elem.name;

		return *this;
	}

	bool operator ==(const TestElemHeap& elem) {
		return name.compare(elem.name) == 0;
	}

	int64_t indexPrio1;
	int64_t prio1;
	int64_t indexPrio2;
	uint64_t prio2;
	std::string name;
};

typedef Heap<TestElemHeap, int64_t, &TestElemHeap::prio1, std::greater<int64_t>> TestHeap1;

void Kernel::Start() {

	TestHeap1 heap1;
	TestElemHeap* elem;
	TestElemHeap elem1(std::string("3"));
	TestElemHeap elem2(std::string("20"));
	TestElemHeap elem3(std::string("1"));
	TestElemHeap elem4(std::string("10"));

	heap1.insert(&elem1, 3);
	heap1.insert(&elem2, 5);
	heap1.insert(&elem3, 1);
	heap1.insert(&elem4, 10);

	heap1.update(&elem2, 20);

	elem = heap1.top();
	Console::write(elem->name);
	Console::write(" < ");
	heap1.pop();
	elem = heap1.top();
	Console::write(elem->name);
	Console::write(" < ");
	heap1.pop();
	elem = heap1.top();
	Console::write(elem->name);
	Console::write(" < ");
	heap1.pop();
	elem = heap1.top();
	Console::write(elem->name);
	Console::write("\n");
	heap1.pop();
	heap1.pop();

	File* f;
	VirtualMapping* mapping;
	f = KernelFS::getUserApp("test1");
	mapping = Elf64::getVirtualMapping(f);
	PageTable* pgTable = mapping->getPageTable();
	PageTable::setActivePageTable(pgTable);

	char str[512];
	sprintf(str, "0x%x, %i, %i\n", 152, 2, 3);
	Console::write("Hello world !!\n");
	Console::write(str);

	std::vector<char> vec;
	std::string stri("Hello how are U?\n");
	stri+="Fine\n";
	Console::write(stri);

	std::list<int> listInt;
	listInt.push_back(0);

	asm("sti");
	asm("int $49");
	asm("cli");

	PhysicalAllocator::printStats();
}

<commit_msg>Remove useless things in example<commit_after>/*
 * Copyright (c) 2016 Boulanger Guillaume, Chathura Namalgamuwa
 * The file is distributed under the MIT license
 * The license is available in the LICENSE file or at https://github.com/boulangg/phoenix/blob/master/LICENSE
 */

#include "Kernel.hpp"

#include <stdio.h>
#include <vector>
#include <stdlib.h>
#include <string>
#include <list>
#include <functional>

#include "Console.hpp"

#include <mm/PhysicalAllocator.hpp>
#include <mm/VirtualMapping.hpp>
#include <fs/Elf64.hpp>
#include <fs/KernelFS.hpp>
#include <fs/File.hpp>

#include <lib/Heap.hpp>

class TestElemHeap {
public:
	TestElemHeap(std::string name): prio1(0), name(name) {}

	TestElemHeap(const TestElemHeap& elem): prio1(elem.prio1), name(elem.name) {
	}

	int64_t prio1;
	std::string name;
};

typedef Heap<TestElemHeap, int64_t, &TestElemHeap::prio1, std::greater<int64_t>> TestHeap1;

void Kernel::Start() {

	TestHeap1 heap1;
	TestElemHeap* elem;
	TestElemHeap elem1(std::string("3"));
	TestElemHeap elem2(std::string("20"));
	TestElemHeap elem3(std::string("1"));
	TestElemHeap elem4(std::string("10"));

	heap1.insert(&elem1, 3);
	heap1.insert(&elem2, 5);
	heap1.insert(&elem3, 1);
	heap1.insert(&elem4, 10);

	heap1.update(&elem2, 20);

	elem = heap1.top();
	Console::write(elem->name);
	Console::write(" < ");
	heap1.pop();
	elem = heap1.top();
	Console::write(elem->name);
	Console::write(" < ");
	heap1.pop();
	elem = heap1.top();
	Console::write(elem->name);
	Console::write(" < ");
	heap1.pop();
	elem = heap1.top();
	Console::write(elem->name);
	Console::write("\n");
	heap1.pop();
	heap1.pop();

	File* f;
	VirtualMapping* mapping;
	f = KernelFS::getUserApp("test1");
	mapping = Elf64::getVirtualMapping(f);
	PageTable* pgTable = mapping->getPageTable();
	PageTable::setActivePageTable(pgTable);

	char str[512];
	sprintf(str, "0x%x, %i, %i\n", 152, 2, 3);
	Console::write("Hello world !!\n");
	Console::write(str);

	std::vector<char> vec;
	std::string stri("Hello how are U?\n");
	stri+="Fine\n";
	Console::write(stri);

	std::list<int> listInt;
	listInt.push_back(0);

	asm("sti");
	asm("int $49");
	asm("cli");

	PhysicalAllocator::printStats();
}

<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////////
// Name:        3d_aux.cpp
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
#pragma implementation
#pragma interface
#endif

#include "fctsys.h"

#if !wxUSE_GLCANVAS
#error Please set wxUSE_GLCANVAS to 1 in setup.h.
#endif

#include "common.h"
#include "trigo.h"

#include "bitmaps.h"

#include "3d_viewer.h"
#include "3d_struct.h"
#include "trackball.h"

/**************************************************************************/
void Struct3D_Master::Set_Object_Coords(S3D_Vertex * coord, int nbcoord )
/**************************************************************************/
{
int ii;

	/* adjust object scale, rotation and offset position */
	for ( ii = 0; ii < nbcoord; ii++ )
	{
	coord[ii].x *= m_MatScale.x;
	coord[ii].y *= m_MatScale.y;
	coord[ii].z *= m_MatScale.z;
	/* adjust rotation */
	if ( m_MatRotation.x )
		RotatePoint(&coord[ii].y, &coord[ii].z,
			(int)(m_MatRotation.x * 10));
	if ( m_MatRotation.y )
		RotatePoint(&coord[ii].z, &coord[ii].x,
			(int)(m_MatRotation.y * 10));
	if ( m_MatRotation.z )
		RotatePoint(&coord[ii].x, &coord[ii].y,
			(int)(m_MatRotation.z * 10));
	/* adjust offset position (offset is given in UNIT 3D (0.1 inch) */
#define SCALE_3D_CONV (PCB_INTERNAL_UNIT/UNITS3D_TO_UNITSPCB)
	coord[ii].x += m_MatPosition.x * SCALE_3D_CONV;
	coord[ii].y += m_MatPosition.y * SCALE_3D_CONV;
	coord[ii].z += m_MatPosition.z * SCALE_3D_CONV;
	}
}

/************************************************************/
void Set_Object_Data(const S3D_Vertex * coord, int nbcoord )
/************************************************************/
{
int ii;
GLfloat ax,ay,az,bx,by,bz,nx,ny,nz,r;

    /* ignore faces with less than 3 points */
    if (nbcoord < 3) return;

    /* calculate normal direction */
    ax = coord[1].x - coord[0].x;
    ay = coord[1].y - coord[0].y;
    az = coord[1].z - coord[0].z;

    bx = coord[nbcoord-1].x - coord[0].x;
    by = coord[nbcoord-1].y - coord[0].y;
    bz = coord[nbcoord-1].z - coord[0].z;

    nx = ay * bz - az * by;
    ny = az * bx - ax * bz;
    nz = ax * by - ay * bx;

    r = sqrt(nx*nx + ny*ny + nz*nz);
    if (r >= 0.000001) /* avoid division by zero */
	{
		nx /= r; ny /= r; nz /= r;
		glNormal3f(nx,ny,nz);
	}

    /* glBegin/glEnd */
    switch (nbcoord)
	{
		case 3:
			glBegin(GL_TRIANGLES);
			break;

		case 4:
			glBegin(GL_QUADS);
			break;

		default:
			glBegin(GL_POLYGON);
			break;
    }

    /* draw polygon/triangle/quad */
    for (ii = 0; ii < nbcoord; ii++)
	{
		glVertex3f(coord[ii].x * DataScale3D,
					coord[ii].y * DataScale3D,
					coord[ii].z * DataScale3D);
	}

	glEnd();
}

/**********************************************/
GLuint Pcb3D_GLCanvas::DisplayCubeforTest()
/**********************************************/
{
GLuint gllist = glGenLists( 1 );

    glNewList( gllist, GL_COMPILE_AND_EXECUTE );
    /* draw six faces of a cube */
    glBegin(GL_QUADS);
    glNormal3f( 0.0F, 0.0F, 1.0F);
    glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F, 0.5F);
    glVertex3f(-0.5F,-0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F);

    glNormal3f( 0.0F, 0.0F,-1.0F);
    glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F, 0.5F,-0.5F);
    glVertex3f( 0.5F, 0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F);

    glNormal3f( 0.0F, 1.0F, 0.0F);
    glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F, 0.5F,-0.5F);
    glVertex3f(-0.5F, 0.5F,-0.5F); glVertex3f(-0.5F, 0.5F, 0.5F);

    glNormal3f( 0.0F,-1.0F, 0.0F);
    glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F);
    glVertex3f( 0.5F,-0.5F, 0.5F); glVertex3f(-0.5F,-0.5F, 0.5F);

    glNormal3f( 1.0F, 0.0F, 0.0F);
    glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F);
    glVertex3f( 0.5F,-0.5F,-0.5F); glVertex3f( 0.5F, 0.5F,-0.5F);

    glNormal3f(-1.0F, 0.0F, 0.0F);
    glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F,-0.5F, 0.5F);
    glVertex3f(-0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F,-0.5F);
    glEnd();

    glEndList();

	return gllist;
}

/**********************/
/* class Info_3D_Visu */
/**********************/

/* Constructor */
Info_3D_Visu::Info_3D_Visu()
{
int ii;
    m_Beginx = m_Beginy = 0.0;	/* position of mouse */
    m_Zoom = 1.0;				/* field of view in degrees */
	trackball( m_Quat, 0.0, 0.0, 0.0, 0.0 );
	for ( ii = 0; ii < 4; ii++ ) m_Rot[ii] = 0.0;
	m_Layers = 1;
	m_BoardSettings = NULL;
}

Info_3D_Visu::~Info_3D_Visu()
{
}

/*****************************************************************/
/* Classe pour afficher et editer un Vertex (triplet de valeurs),*/
/* en INCHES ou MM ou sans unites								 */
/*****************************************************************/

WinEDA_VertexCtrl::WinEDA_VertexCtrl(wxWindow *parent, const wxString & title,
						wxBoxSizer * BoxSizer,
						int units, int internal_unit)
{
wxString text;
wxStaticText * msgtitle;

	m_Units = units;
	m_Internal_Unit = internal_unit;

	if ( title.IsEmpty()  )	text = _("Vertex ");
	else text = title;
	text += ReturnUnitSymbol(units);

	msgtitle = new wxStaticText(parent, -1, text, wxDefaultPosition, wxSize(-1,-1), 0 );
	BoxSizer->Add(msgtitle, wxGROW|wxLEFT|wxRIGHT|wxTOP|wxBOTTOM|wxADJUST_MINSIZE);

    wxFlexGridSizer * GridSizer = new wxFlexGridSizer(3, 2, 0, 0);
    BoxSizer->Add(GridSizer, 0, wxGROW|wxALL, 5);

	msgtitle = new wxStaticText(parent, -1, wxT("X:"));
    GridSizer->Add(msgtitle, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxADJUST_MINSIZE, 5);
	m_XValueCtrl = new wxTextCtrl(parent, -1, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0 );
	GridSizer->Add(m_XValueCtrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5);

	msgtitle = new wxStaticText(parent, -1, wxT("Y:"), wxDefaultPosition, wxSize(-1,-1), 0 );
    GridSizer->Add(msgtitle, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxADJUST_MINSIZE, 5);
	m_YValueCtrl = new wxTextCtrl(parent, -1, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0 );
	GridSizer->Add(m_YValueCtrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5);

	msgtitle = new wxStaticText(parent, -1, wxT("Z:"), wxDefaultPosition, wxSize(-1,-1), 0 );
	GridSizer->Add(msgtitle, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxADJUST_MINSIZE, 5);
	m_ZValueCtrl = new wxTextCtrl(parent, -1, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0 );
	GridSizer->Add(m_ZValueCtrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5);
}

WinEDA_VertexCtrl::~WinEDA_VertexCtrl()
{
}

/*******************************************/
S3D_Vertex WinEDA_VertexCtrl::GetValue()
/*******************************************/
/* Retourne (en unites internes) les coordonnes entrees (en unites utilisateur)
*/
{
S3D_Vertex value;
double dtmp;

	m_XValueCtrl->GetValue().ToDouble(&dtmp);
	value.x = dtmp;
	m_YValueCtrl->GetValue().ToDouble(&dtmp);
	value.y = dtmp;
	m_ZValueCtrl->GetValue().ToDouble(&dtmp);
	value.z = dtmp;
	return value;
}

/**************************************************/
void WinEDA_VertexCtrl::SetValue(S3D_Vertex vertex)
/**************************************************/
{
wxString text;

	text.Printf( wxT("%f"), vertex.x);
	m_XValueCtrl->Clear();
	m_XValueCtrl->AppendText(text);

	text.Printf(wxT("%f"), vertex.y);
	m_YValueCtrl->Clear();
	m_YValueCtrl->AppendText(text);

	text.Printf(wxT("%f"), vertex.z);
	m_ZValueCtrl->Clear();
	m_ZValueCtrl->AppendText(text);
}

/*****************************************/
void WinEDA_VertexCtrl::Enable(bool onoff)
/*****************************************/
{
	m_XValueCtrl->Enable(onoff);
	m_YValueCtrl->Enable(onoff);
	m_ZValueCtrl->Enable(onoff);
}

<commit_msg>beautified<commit_after>/////////////////////////////////////////////////////////////////////////////

// Name:        3d_aux.cpp
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
#pragma implementation
#pragma interface
#endif

#include "fctsys.h"

#if !wxUSE_GLCANVAS
#error Please set wxUSE_GLCANVAS to 1 in setup.h.
#endif

#include "common.h"
#include "trigo.h"

#include "bitmaps.h"

#include "3d_viewer.h"
#include "3d_struct.h"
#include "trackball.h"

/**************************************************************************/
void Struct3D_Master::Set_Object_Coords( S3D_Vertex* coord, int nbcoord )
/**************************************************************************/
{
    int ii;

    /* adjust object scale, rotation and offset position */
    for( ii = 0; ii < nbcoord; ii++ )
    {
        coord[ii].x *= m_MatScale.x;
        coord[ii].y *= m_MatScale.y;
        coord[ii].z *= m_MatScale.z;
        /* adjust rotation */
        if( m_MatRotation.x )
            RotatePoint( &coord[ii].y, &coord[ii].z,
                (int) (m_MatRotation.x * 10) );
        if( m_MatRotation.y )
            RotatePoint( &coord[ii].z, &coord[ii].x,
                (int) (m_MatRotation.y * 10) );
        if( m_MatRotation.z )
            RotatePoint( &coord[ii].x, &coord[ii].y,
                (int) (m_MatRotation.z * 10) );
        /* adjust offset position (offset is given in UNIT 3D (0.1 inch) */
#define SCALE_3D_CONV (PCB_INTERNAL_UNIT / UNITS3D_TO_UNITSPCB)
        coord[ii].x += m_MatPosition.x * SCALE_3D_CONV;
        coord[ii].y += m_MatPosition.y * SCALE_3D_CONV;
        coord[ii].z += m_MatPosition.z * SCALE_3D_CONV;
    }
}

/************************************************************/
void Set_Object_Data( const S3D_Vertex* coord, int nbcoord )
/************************************************************/
{
    int     ii;
    GLfloat ax, ay, az, bx, by, bz, nx, ny, nz, r;

    /* ignore faces with less than 3 points */
    if( nbcoord < 3 )
        return;

    /* calculate normal direction */
    ax = coord[1].x - coord[0].x;
    ay = coord[1].y - coord[0].y;
    az = coord[1].z - coord[0].z;

    bx = coord[nbcoord - 1].x - coord[0].x;
    by = coord[nbcoord - 1].y - coord[0].y;
    bz = coord[nbcoord - 1].z - coord[0].z;

    nx = ay * bz - az * by;
    ny = az * bx - ax * bz;
    nz = ax * by - ay * bx;

    r = sqrt( nx * nx + ny * ny + nz * nz );
    if( r >= 0.000001 ) /* avoid division by zero */
    {
        nx /= r; ny /= r; nz /= r;
        glNormal3f( nx, ny, nz );
    }

    /* glBegin/glEnd */
    switch( nbcoord )
    {
    case 3:
        glBegin( GL_TRIANGLES );
        break;

    case 4:
        glBegin( GL_QUADS );
        break;

    default:
        glBegin( GL_POLYGON );
        break;
    }

    /* draw polygon/triangle/quad */
    for( ii = 0; ii < nbcoord; ii++ )
    {
        glVertex3f( coord[ii].x * DataScale3D,
            coord[ii].y * DataScale3D,
            coord[ii].z * DataScale3D );
    }

    glEnd();
}

/**********************************************/
GLuint Pcb3D_GLCanvas::DisplayCubeforTest()
/**********************************************/
{
    GLuint gllist = glGenLists( 1 );

    glNewList( gllist, GL_COMPILE_AND_EXECUTE );
    /* draw six faces of a cube */
    glBegin( GL_QUADS );
    glNormal3f( 0.0F, 0.0F, 1.0F );
    glVertex3f( 0.5F, 0.5F, 0.5F ); glVertex3f( -0.5F, 0.5F, 0.5F );
    glVertex3f( -0.5F, -0.5F, 0.5F ); glVertex3f( 0.5F, -0.5F, 0.5F );

    glNormal3f( 0.0F, 0.0F, -1.0F );
    glVertex3f( -0.5F, -0.5F, -0.5F ); glVertex3f( -0.5F, 0.5F, -0.5F );
    glVertex3f( 0.5F, 0.5F, -0.5F ); glVertex3f( 0.5F, -0.5F, -0.5F );

    glNormal3f( 0.0F, 1.0F, 0.0F );
    glVertex3f( 0.5F, 0.5F, 0.5F ); glVertex3f( 0.5F, 0.5F, -0.5F );
    glVertex3f( -0.5F, 0.5F, -0.5F ); glVertex3f( -0.5F, 0.5F, 0.5F );

    glNormal3f( 0.0F, -1.0F, 0.0F );
    glVertex3f( -0.5F, -0.5F, -0.5F ); glVertex3f( 0.5F, -0.5F, -0.5F );
    glVertex3f( 0.5F, -0.5F, 0.5F ); glVertex3f( -0.5F, -0.5F, 0.5F );

    glNormal3f( 1.0F, 0.0F, 0.0F );
    glVertex3f( 0.5F, 0.5F, 0.5F ); glVertex3f( 0.5F, -0.5F, 0.5F );
    glVertex3f( 0.5F, -0.5F, -0.5F ); glVertex3f( 0.5F, 0.5F, -0.5F );

    glNormal3f( -1.0F, 0.0F, 0.0F );
    glVertex3f( -0.5F, -0.5F, -0.5F ); glVertex3f( -0.5F, -0.5F, 0.5F );
    glVertex3f( -0.5F, 0.5F, 0.5F ); glVertex3f( -0.5F, 0.5F, -0.5F );
    glEnd();

    glEndList();

    return gllist;
}

/**********************/
/* class Info_3D_Visu */
/**********************/

/* Constructor */
Info_3D_Visu::Info_3D_Visu()
{
    int ii;

    m_Beginx = m_Beginy = 0.0;  /* position of mouse */
    m_Zoom   = 1.0;             /* field of view in degrees */
    trackball( m_Quat, 0.0, 0.0, 0.0, 0.0 );
    for( ii = 0; ii < 4; ii++ )
        m_Rot[ii] = 0.0;

    m_Layers = 1;
    m_BoardSettings = NULL;
}

Info_3D_Visu::~Info_3D_Visu()
{
}

/*****************************************************************/
/* Classe pour afficher et editer un Vertex (triplet de valeurs),*/
/* en INCHES ou MM ou sans unites								 */
/*****************************************************************/

WinEDA_VertexCtrl::WinEDA_VertexCtrl( wxWindow* parent, const wxString& title,
                                      wxBoxSizer* BoxSizer,
                                      int units, int internal_unit )
{
    wxString      text;
    wxStaticText* msgtitle;

    m_Units = units;
    m_Internal_Unit = internal_unit;

    if( title.IsEmpty() )
        text = _( "Vertex " );
    else
        text = title;
    text += ReturnUnitSymbol( units );

    msgtitle = new                      wxStaticText( parent, -1, text, wxDefaultPosition, wxSize(
                                                          -1,
                                                          -1 ), 0 );

    BoxSizer->Add( msgtitle, wxGROW | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM | wxADJUST_MINSIZE );

    wxFlexGridSizer* GridSizer = new    wxFlexGridSizer( 3, 2, 0, 0 );

    BoxSizer->Add( GridSizer, 0, wxGROW | wxALL, 5 );

    msgtitle = new                      wxStaticText( parent, -1, wxT( "X:" ) );

    GridSizer->Add( msgtitle,
        0,
        wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxADJUST_MINSIZE,
        5 );
    m_XValueCtrl = new                  wxTextCtrl( parent,
                                                    -1,
                                                    wxEmptyString,
                                                    wxDefaultPosition,
                                                    wxSize( -1, -1 ),
                                                    0 );

    GridSizer->Add( m_XValueCtrl,
        0,
        wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
        5 );

    msgtitle = new                      wxStaticText( parent, -1, wxT(
                                                          "Y:" ), wxDefaultPosition, wxSize( -1,
                                                          -1 ), 0 );

    GridSizer->Add( msgtitle,
        0,
        wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxADJUST_MINSIZE,
        5 );
    m_YValueCtrl = new                  wxTextCtrl( parent,
                                                    -1,
                                                    wxEmptyString,
                                                    wxDefaultPosition,
                                                    wxSize( -1, -1 ),
                                                    0 );

    GridSizer->Add( m_YValueCtrl,
        0,
        wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
        5 );

    msgtitle = new                      wxStaticText( parent, -1, wxT(
                                                          "Z:" ), wxDefaultPosition, wxSize( -1,
                                                          -1 ), 0 );

    GridSizer->Add( msgtitle,
        0,
        wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxADJUST_MINSIZE,
        5 );
    m_ZValueCtrl = new                  wxTextCtrl( parent,
                                                    -1,
                                                    wxEmptyString,
                                                    wxDefaultPosition,
                                                    wxSize( -1, -1 ),
                                                    0 );

    GridSizer->Add( m_ZValueCtrl,
        0,
        wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
        5 );
}

WinEDA_VertexCtrl::~WinEDA_VertexCtrl()
{
}

/*******************************************/
S3D_Vertex WinEDA_VertexCtrl::GetValue()
/*******************************************/

/* Retourne (en unites internes) les coordonnes entrees (en unites utilisateur)
 */
{
    S3D_Vertex value;
    double     dtmp;

    m_XValueCtrl->GetValue().ToDouble( &dtmp );
    value.x = dtmp;
    m_YValueCtrl->GetValue().ToDouble( &dtmp );
    value.y = dtmp;
    m_ZValueCtrl->GetValue().ToDouble( &dtmp );
    value.z = dtmp;
    return value;
}

/**************************************************/
void WinEDA_VertexCtrl::SetValue( S3D_Vertex vertex )
/**************************************************/
{
    wxString text;

    text.Printf( wxT( "%f" ), vertex.x );
    m_XValueCtrl->Clear();
    m_XValueCtrl->AppendText( text );

    text.Printf( wxT( "%f" ), vertex.y );
    m_YValueCtrl->Clear();
    m_YValueCtrl->AppendText( text );

    text.Printf( wxT( "%f" ), vertex.z );
    m_ZValueCtrl->Clear();
    m_ZValueCtrl->AppendText( text );
}

/*****************************************/
void WinEDA_VertexCtrl::Enable( bool onoff )
/*****************************************/
{
    m_XValueCtrl->Enable( onoff );
    m_YValueCtrl->Enable( onoff );
    m_ZValueCtrl->Enable( onoff );
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// transaction_test.cpp
//
// Identification: tests/concurrency/transaction_test.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "harness.h"
#include "concurrency/transaction_tests_util.h"

namespace peloton {

namespace test {

//===--------------------------------------------------------------------===//
// Transaction Tests
//===--------------------------------------------------------------------===//

class TransactionTests : public PelotonTest {};

static std::vector<ConcurrencyType> TEST_TYPES = {CONCURRENCY_TYPE_OCC,
                                                  CONCURRENCY_TYPE_2PL};

void TransactionTest(concurrency::TransactionManager *txn_manager) {
  uint64_t thread_id = TestingHarness::GetInstance().GetThreadId();

  for (oid_t txn_itr = 1; txn_itr <= 50; txn_itr++) {
    txn_manager->BeginTransaction();
    if (thread_id % 2 == 0) {
      std::chrono::microseconds sleep_time(1);
      std::this_thread::sleep_for(sleep_time);
    }

    if (txn_itr % 25 != 0) {
      txn_manager->CommitTransaction();
    } else {
      txn_manager->AbortTransaction();
    }
  }
}

TEST_F(TransactionTests, TransactionTest) {
  for (auto test_type : TEST_TYPES) {
    concurrency::TransactionManagerFactory::Configure(test_type);
    auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();

    LaunchParallelTest(8, TransactionTest, &txn_manager);

    std::cout << "next Commit Id :: " << txn_manager.GetNextCommitId() << "\n";
  }
}

TEST_F(TransactionTests, SingleTransactionTest) {
  for (auto test_type : TEST_TYPES) {
    concurrency::TransactionManagerFactory::Configure(test_type);
    auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
    std::unique_ptr<storage::DataTable> table(
        TransactionTestsUtil::CreateTable());
    // read, read, read, read, update, read
    {
      TransactionScheduler scheduler(1, table.get(), &txn_manager);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Update(0, 1);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Commit();

      scheduler.Run();

      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[0].txn_result);
      EXPECT_EQ(0, scheduler.schedules[0].results[0]);
      EXPECT_EQ(0, scheduler.schedules[0].results[1]);
      EXPECT_EQ(0, scheduler.schedules[0].results[2]);
      EXPECT_EQ(0, scheduler.schedules[0].results[3]);
      EXPECT_EQ(1, scheduler.schedules[0].results[4]);
    }

    // update, update, update, update
    {
      TransactionScheduler scheduler(1, table.get(), &txn_manager);
      scheduler.Txn(0).Update(0, 1);
      scheduler.Txn(0).Update(0, 2);
      scheduler.Txn(0).Update(0, 3);
      scheduler.Txn(0).Update(0, 4);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Commit();

      scheduler.Run();

      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[0].txn_result);
      EXPECT_EQ(4, scheduler.schedules[0].results[0]);
    }
  }
}

TEST_F(TransactionTests, AbortTest) {
  for (auto test_type : TEST_TYPES) {
    concurrency::TransactionManagerFactory::Configure(test_type);
    auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
    std::unique_ptr<storage::DataTable> table(
        TransactionTestsUtil::CreateTable());
    {
      TransactionScheduler scheduler(2, table.get(), &txn_manager);
      scheduler.Txn(0).Update(0, 100);
      scheduler.Txn(0).Abort();
      scheduler.Txn(1).Read(0);
      scheduler.Txn(1).Commit();

      scheduler.Run();

      EXPECT_EQ(RESULT_ABORTED, scheduler.schedules[0].txn_result);
      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[1].txn_result);
      EXPECT_EQ(0, scheduler.schedules[1].results[0]);
    }

    {
      TransactionScheduler scheduler(2, table.get(), &txn_manager);
      scheduler.Txn(0).Insert(100, 0);
      scheduler.Txn(0).Abort();
      scheduler.Txn(1).Read(100);
      scheduler.Txn(1).Commit();

      scheduler.Run();
      EXPECT_EQ(RESULT_ABORTED, scheduler.schedules[0].txn_result);
      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[1].txn_result);
      EXPECT_EQ(-1, scheduler.schedules[1].results[0]);
    }
  }
}

}  // End test namespace
}  // End peloton namespace
<commit_msg>more single txn test<commit_after>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// transaction_test.cpp
//
// Identification: tests/concurrency/transaction_test.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "harness.h"
#include "concurrency/transaction_tests_util.h"

namespace peloton {

namespace test {

//===--------------------------------------------------------------------===//
// Transaction Tests
//===--------------------------------------------------------------------===//

class TransactionTests : public PelotonTest {};

static std::vector<ConcurrencyType> TEST_TYPES = {CONCURRENCY_TYPE_OCC,
                                                  CONCURRENCY_TYPE_2PL};

void TransactionTest(concurrency::TransactionManager *txn_manager) {
  uint64_t thread_id = TestingHarness::GetInstance().GetThreadId();

  for (oid_t txn_itr = 1; txn_itr <= 50; txn_itr++) {
    txn_manager->BeginTransaction();
    if (thread_id % 2 == 0) {
      std::chrono::microseconds sleep_time(1);
      std::this_thread::sleep_for(sleep_time);
    }

    if (txn_itr % 25 != 0) {
      txn_manager->CommitTransaction();
    } else {
      txn_manager->AbortTransaction();
    }
  }
}

TEST_F(TransactionTests, TransactionTest) {
  for (auto test_type : TEST_TYPES) {
    concurrency::TransactionManagerFactory::Configure(test_type);
    auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();

    LaunchParallelTest(8, TransactionTest, &txn_manager);

    std::cout << "next Commit Id :: " << txn_manager.GetNextCommitId() << "\n";
  }
}

TEST_F(TransactionTests, SingleTransactionTest) {
  for (auto test_type : TEST_TYPES) {
    concurrency::TransactionManagerFactory::Configure(test_type);
    auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
    std::unique_ptr<storage::DataTable> table(
        TransactionTestsUtil::CreateTable());
    // read, read, read, read, update, read, read not exist
    // another txn read
    {
      TransactionScheduler scheduler(2, table.get(), &txn_manager);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Update(0, 1);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Read(100);
      scheduler.Txn(0).Commit();
      scheduler.Txn(1).Read(0);
      scheduler.Txn(1).Commit();

      scheduler.Run();

      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[0].txn_result);
      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[1].txn_result);
      EXPECT_EQ(0, scheduler.schedules[0].results[0]);
      EXPECT_EQ(0, scheduler.schedules[0].results[1]);
      EXPECT_EQ(0, scheduler.schedules[0].results[2]);
      EXPECT_EQ(0, scheduler.schedules[0].results[3]);
      EXPECT_EQ(1, scheduler.schedules[0].results[4]);
      EXPECT_EQ(-1, scheduler.schedules[0].results[5]);
      EXPECT_EQ(1, scheduler.schedules[1].results[0]);
    }

    // update, update, update, update, read
    {
      TransactionScheduler scheduler(1, table.get(), &txn_manager);
      scheduler.Txn(0).Update(0, 1);
      scheduler.Txn(0).Update(0, 2);
      scheduler.Txn(0).Update(0, 3);
      scheduler.Txn(0).Update(0, 4);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Commit();

      scheduler.Run();

      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[0].txn_result);
      EXPECT_EQ(4, scheduler.schedules[0].results[0]);
    }

    // delete not exist, delete exist, read deleted, update deleted,
    // read deleted, insert back, update inserted, read newly updated
    {
      TransactionScheduler scheduler(1, table.get(), &txn_manager);

      scheduler.Txn(0).Delete(100);
      scheduler.Txn(0).Delete(0);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Update(0, 1);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Insert(0, 2);
      scheduler.Txn(0).Update(0, 3);
      scheduler.Txn(0).Read(0);
      scheduler.Txn(0).Commit();

      scheduler.Run();

      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[0].txn_result);
      EXPECT_EQ(-1, scheduler.schedules[0].results[0]);
      EXPECT_EQ(-1, scheduler.schedules[0].results[1]);
      EXPECT_EQ(3, scheduler.schedules[0].results[2]);
    }

    // insert, delete inserted, read deleted, insert again, delete again
    // read deleted, insert again, read inserted, update inserted, read updated
    {
      TransactionScheduler scheduler(1, table.get(), &txn_manager);

      scheduler.Txn(0).Insert(1000, 0);
      scheduler.Txn(0).Delete(1000);
      scheduler.Txn(0).Read(1000);
      scheduler.Txn(0).Insert(1000, 1);
      scheduler.Txn(0).Delete(1000);
      scheduler.Txn(0).Read(1000);
      scheduler.Txn(0).Insert(1000, 2);
      scheduler.Txn(0).Read(1000);
      scheduler.Txn(0).Update(1000, 3);
      scheduler.Txn(0).Read(1000);
      scheduler.Txn(0).Commit();

      scheduler.Run();

      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[0].txn_result);
      EXPECT_EQ(-1, scheduler.schedules[0].results[0]);
      EXPECT_EQ(-1, scheduler.schedules[0].results[1]);
      EXPECT_EQ(2, scheduler.schedules[0].results[2]);
      EXPECT_EQ(3, scheduler.schedules[0].results[3]);
    }
  }
}

TEST_F(TransactionTests, AbortTest) {
  for (auto test_type : TEST_TYPES) {
    concurrency::TransactionManagerFactory::Configure(test_type);
    auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
    std::unique_ptr<storage::DataTable> table(
        TransactionTestsUtil::CreateTable());
    {
      TransactionScheduler scheduler(2, table.get(), &txn_manager);
      scheduler.Txn(0).Update(0, 100);
      scheduler.Txn(0).Abort();
      scheduler.Txn(1).Read(0);
      scheduler.Txn(1).Commit();

      scheduler.Run();

      EXPECT_EQ(RESULT_ABORTED, scheduler.schedules[0].txn_result);
      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[1].txn_result);
      EXPECT_EQ(0, scheduler.schedules[1].results[0]);
    }

    {
      TransactionScheduler scheduler(2, table.get(), &txn_manager);
      scheduler.Txn(0).Insert(100, 0);
      scheduler.Txn(0).Abort();
      scheduler.Txn(1).Read(100);
      scheduler.Txn(1).Commit();

      scheduler.Run();
      EXPECT_EQ(RESULT_ABORTED, scheduler.schedules[0].txn_result);
      EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[1].txn_result);
      EXPECT_EQ(-1, scheduler.schedules[1].results[0]);
    }
  }
}

}  // End test namespace
}  // End peloton namespace
<|endoftext|>