<commit_before>#include "facepreprocessor.h"

#include <vector>
#include <algorithm>
#include <limits>
#include <cstdint>

#include <opencv2/imgproc/imgproc.hpp>

#include <QDebug>

static const double PI = std::atan(1.0) * 4;

using namespace cv;

static const bool MARK_FOUND_FEATURES = false;

FacePreprocessor::FacePreprocessor(FaceClassifiers classifiers, const Mat& input)  throw(std::invalid_argument)
    : input(input),
      result(Mat(input.rows, input.cols, CV_8UC1)),
      classifiers(classifiers)
{
    if (classifiers.face.get() == nullptr)
        throw std::invalid_argument("face classifier");
    else if (classifiers.face->empty())
        throw std::invalid_argument("face classifier");
    else if (classifiers.eye.get() == nullptr)
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eye->empty())
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eyePair.get() == nullptr)
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyePair->empty())
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyeLeft.get() == nullptr)
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeLeft->empty())
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeRight.get() == nullptr)
        throw std::invalid_argument("right eye classifier");
    else if (classifiers.eyeRight->empty())
        throw std::invalid_argument("right eye classifier");
}

unsigned int FacePreprocessor::GetMinSize() const
{
    int minDim = std::min(input.rows, input.cols);
    return static_cast<unsigned int>(minDim / 5.0);
}

Rect FacePreprocessor::LargestRect(const std::vector<Rect>& rects)
{
    if(rects.empty())
        return Rect();
    Rect largest = *std::max_element(rects.begin(), rects.end(), [](const Rect& a, const Rect& b)
    {
        return a.area() < b.area();
    }
    );
    return largest;
}

const double FacePreprocessor::MAX_ROTATE_ANGLE = 20.0;

double FacePreprocessor::GetRotation(cv::Rect left, cv::Rect right)
{
    Point direction;
    direction.x = right.x - left.x;
    direction.y = right.y - left.y;
    double angle = std::atan2(direction.y, direction.x) * 180.0 / PI;
    return angle;
}

std::vector<Rect> FacePreprocessor::GetEyesAlternateMethod()
{
    static std::vector<Rect> empty;
    std::vector<Rect> eyes;
    eyes.reserve(2);
    classifiers.eyePair->detectMultiScale(result, eyes, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyes.empty())
        return empty;
    qDebug() << "eye pair was found";
    if (MARK_FOUND_FEATURES)
        rectangle(result, eyes.front(), 1);

    std::vector<Rect> lefts;
    std::vector<Rect> rights;
    Rect cRect = eyes.front();
    cRect.width /= 2;
    classifiers.eyeLeft->detectMultiScale(result(cRect), lefts, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(lefts.empty())
    {
        qDebug () << "left wasnt found";
        return empty;
    }
    cRect.x += cRect.width;
    classifiers.eyeLeft->detectMultiScale(result(cRect), rights, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(rights.empty())
    {
        qDebug () << "right wasnt found";
        return empty;
    }
    rights.front().x += cRect.width;

    gotEyes = true;

    lefts.front().x += eyes.front().x;
    lefts.front().y += eyes.front().y;
    rights.front().x += eyes.front().x;
    rights.front().y += eyes.front().y;
    if (MARK_FOUND_FEATURES)
    {
        rectangle(result, lefts.front(), 1);
        rectangle(result, rights.front(), 1);
    }

    eyes.clear();
    eyes.push_back(lefts.front());
    eyes.push_back(rights.front());
    return eyes;
}

std::vector<Rect> FacePreprocessor::GetEyes()
{
    int maxSize = static_cast<int>(std::ceil(std::max(result.rows, result.cols) / 6.0));
    int minSize = std::max(static_cast<int>(std::floor(std::min(result.rows, result.cols) / 20.0)), 5);
    Rect upperHalfOfFace(0, 0, face.width, static_cast<int>(face.height / 1.8));
    std::vector<Rect> eyes;
    std::vector<Rect> eyePairR;
    //classifiers.eyePair->detectMultiScale(result(upperHalfOfFace), eyePairR, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyePairR.empty())
    {
        classifiers.eye->detectMultiScale(result(upperHalfOfFace), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
    }
    else
    {
        classifiers.eye->detectMultiScale(result(eyePairR.front()), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
        if (MARK_FOUND_FEATURES)
            rectangle(result, eyePairR.front(), 255);
    }
    for (auto eye : eyes)
    {
        if(!eyePairR.empty())
        {
            eye.x += eyePairR.front().x;
            eye.y += eyePairR.front().y;
        }
        if (MARK_FOUND_FEATURES)
            rectangle(result, eye, 1);
    }
    if(eyes.size() < 2)
    {
        qDebug() << "only" << eyes.size() << "eyes were found";
        eyes.clear();
        return eyes;
    }
    gotEyes = true;

    for(uint8_t i = 0; i < eyes.size(); i++)
    {
        for(uint8_t j = 0; j < eyes.size(); j++)
        {
            if (i != j)
            {
                Rect intersection = eyes[i] & eyes[j];
                if (intersection.area() > 0)
                {
                    eyes.erase(eyes.begin() + j);
                    if (i > j)
                        i--;
                    j--;
                }
            }
        }
    }

    if(eyes.size() > 2)
    {
        // finding the pair with lowest angle
        std::vector<std::pair<uint16_t, uint16_t>> helper;
        helper.reserve(eyes.size() * eyes.size() - eyes.size());
        for(auto i = eyes.begin(); i != eyes.end(); i++)
        {
            for(auto j = eyes.begin(); j != eyes.end(); j++)
            {
                if (i != j)
                    helper.push_back(std::make_pair(std::distance(eyes.begin(), i), std::distance(eyes.begin(), j)));
            }
        }

        std::sort(helper.begin(), helper.end(), [&eyes](const std::pair<uint16_t, uint16_t>& a, const std::pair<uint16_t, uint16_t>& b)
        {
            double angleA = std::abs(GetRotation(eyes[a.first], eyes[a.second]));
            double angleB = std::abs(GetRotation(eyes[b.first], eyes[b.second]));
            return angleA < angleB;
        });

        assert(helper.front().first != helper.front().second);

        std::swap(eyes[0], eyes[helper.front().first]);
        std::swap(eyes[1], eyes[helper.front().second]);
    }

    std::sort(eyes.begin(), eyes.begin() + 2, [](const Rect& a, const Rect& b) { return a.x < b.x; });
    eyes.resize(2);
    return eyes;
}

void FacePreprocessor::RotateFace()
{
    std::vector<Rect> eyes = GetEyes();
    if(eyes.size() < 2)
    {
        return;
    }

    double angle = GetRotation(eyes[0], eyes[1]);
    qDebug() << "rotation angle: " << angle;
    if (std::abs(angle) < std::numeric_limits<double>::epsilon() * 3 || std::abs(angle) > MAX_ROTATE_ANGLE)
        return;

    int size = std::max(result.cols, result.rows);
    int fullSize = std::max(normalized.cols, normalized.rows);
    Point2f pt(size/2.0f + face.x, size/2.0f + face.y);
    Mat r = getRotationMatrix2D(pt, angle, 1.0);

    warpAffine(normalized, rotated, r, Size(fullSize, fullSize), CV_INTER_LANCZOS4);

    result = rotated(face);
}

void FacePreprocessor::ScaleFace()
{
    Rect aspected = face;
    if(face.width < face.height)
    {
        aspected.width = face.height;
    }
    else
    {
        aspected.height = face.width;
    }

    Mat scaled = result.clone();

    copyMakeBorder(scaled, scaled, 0, aspected.height, 0, aspected.width, BORDER_REPLICATE);

    aspected.x = 0;
    aspected.y = 0;

    result = scaled(aspected);
    resize(result, result, Size(512, 512), 0.0, 0.0, CV_INTER_LANCZOS4);
}

double FacePreprocessor::GetAccuracy() const
{
    double accuracy = 0.0;
    if(face.width > 0 && face.height > 0)
        accuracy += 0.5;
    if(gotEyes)
        accuracy += 0.25;
    if(!rotated.empty())
        accuracy += 0.25;
    return accuracy;
}

Mat FacePreprocessor::Preprocess() throw (NoFaceFoundException)
{
    if(input.type() == CV_8UC3)
        cvtColor(input, result, CV_BGR2GRAY);
    else
        result = input;
    equalizeHist(result, normalized);

    result = normalized;

    std::vector<Rect> faces;
    Size minSize(GetMinSize(), GetMinSize());
    classifiers.face->detectMultiScale(result, faces, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT, minSize);

    if (!faces.empty())
    {
        face = LargestRect(faces);

        result = result(face);
    }
    else
    {
        throw NoFaceFoundException();
    }

    RotateFace();

    static uint64_t eyesFoundCntr = 0;
    static uint64_t totalRunCntr = 0;

    totalRunCntr++;

    if(!gotEyes)
        qDebug() << "no eyes were found on the face -- this is odd :(" << ++eyesFoundCntr << "/" << totalRunCntr;
    else
        qDebug() << "is rotated? " << !rotated.empty() << (totalRunCntr - eyesFoundCntr) << "/" << totalRunCntr;

    ScaleFace();

    return result;
}
<commit_msg>refactor + wider search range for eyes<commit_after>#include "facepreprocessor.h"

#include <vector>
#include <algorithm>
#include <limits>
#include <cstdint>

#include <opencv2/imgproc/imgproc.hpp>

#include <QDebug>

static const double PI = std::atan(1.0) * 4;

using namespace cv;

static const bool MARK_FOUND_FEATURES = false;

FacePreprocessor::FacePreprocessor(FaceClassifiers classifiers, const Mat& input)  throw(std::invalid_argument)
    : input(input),
      result(Mat(input.rows, input.cols, CV_8UC1)),
      classifiers(classifiers)
{
    if (classifiers.face.get() == nullptr)
        throw std::invalid_argument("face classifier");
    else if (classifiers.face->empty())
        throw std::invalid_argument("face classifier");
    else if (classifiers.eye.get() == nullptr)
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eye->empty())
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eyePair.get() == nullptr)
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyePair->empty())
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyeLeft.get() == nullptr)
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeLeft->empty())
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeRight.get() == nullptr)
        throw std::invalid_argument("right eye classifier");
    else if (classifiers.eyeRight->empty())
        throw std::invalid_argument("right eye classifier");
}

unsigned int FacePreprocessor::GetMinSize() const
{
    int minDim = std::min(input.rows, input.cols);
    return static_cast<unsigned int>(minDim / 5.0);
}

Rect FacePreprocessor::LargestRect(const std::vector<Rect>& rects)
{
    if(rects.empty())
        return Rect();
    Rect largest = *std::max_element(rects.begin(), rects.end(), [](const Rect& a, const Rect& b)
    {
        return a.area() < b.area();
    }
    );
    return largest;
}

const double FacePreprocessor::MAX_ROTATE_ANGLE = 20.0;

double FacePreprocessor::GetRotation(cv::Rect left, cv::Rect right)
{
    Point direction;
    direction.x = right.x - left.x;
    direction.y = right.y - left.y;
    double angle = std::atan2(direction.y, direction.x) * 180.0 / PI;
    return angle;
}

std::vector<Rect> FacePreprocessor::GetEyesAlternateMethod()
{
    static std::vector<Rect> empty;
    std::vector<Rect> eyes;
    eyes.reserve(2);
    classifiers.eyePair->detectMultiScale(result, eyes, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyes.empty())
        return empty;
    qDebug() << "eye pair was found";
    if (MARK_FOUND_FEATURES)
        rectangle(result, eyes.front(), 1);

    std::vector<Rect> lefts;
    std::vector<Rect> rights;
    Rect cRect = eyes.front();
    cRect.width /= 2;
    classifiers.eyeLeft->detectMultiScale(result(cRect), lefts, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(lefts.empty())
    {
        qDebug () << "left wasnt found";
        return empty;
    }
    cRect.x += cRect.width;
    classifiers.eyeLeft->detectMultiScale(result(cRect), rights, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(rights.empty())
    {
        qDebug () << "right wasnt found";
        return empty;
    }
    rights.front().x += cRect.width;

    gotEyes = true;

    lefts.front().x += eyes.front().x;
    lefts.front().y += eyes.front().y;
    rights.front().x += eyes.front().x;
    rights.front().y += eyes.front().y;
    if (MARK_FOUND_FEATURES)
    {
        rectangle(result, lefts.front(), 1);
        rectangle(result, rights.front(), 1);
    }

    eyes.clear();
    eyes.push_back(lefts.front());
    eyes.push_back(rights.front());
    return eyes;
}

std::vector<Rect> FacePreprocessor::GetEyes()
{
    const Rect upperHalfOfFace(0, 0, face.width, static_cast<int>(face.height / 1.8));
    const int maxSize = static_cast<int>(std::ceil(std::max(upperHalfOfFace.width, upperHalfOfFace.height) / 5.0));
    const int minSize = std::max(static_cast<int>(std::floor(std::min(upperHalfOfFace.width, upperHalfOfFace.height) / 20.0)), 3);
    std::vector<Rect> eyes;
    std::vector<Rect> eyePairR;
    //classifiers.eyePair->detectMultiScale(result(upperHalfOfFace), eyePairR, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyePairR.empty())
    {
        classifiers.eye->detectMultiScale(result(upperHalfOfFace), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
    }
    else
    {
        classifiers.eye->detectMultiScale(result(eyePairR.front()), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
        if (MARK_FOUND_FEATURES)
            rectangle(result, eyePairR.front(), 255);
    }
    for (auto eye : eyes)
    {
        if(!eyePairR.empty())
        {
            eye.x += eyePairR.front().x;
            eye.y += eyePairR.front().y;
        }
        if (MARK_FOUND_FEATURES)
            rectangle(result, eye, 1);
    }
    if(eyes.size() < 2)
    {
        qDebug() << "only" << eyes.size() << "eyes were found";
        eyes.clear();
        return eyes;
    }
    gotEyes = true;

    for(uint8_t i = 0; i < eyes.size(); i++)
    {
        for(uint8_t j = 0; j < eyes.size(); j++)
        {
            if (i != j)
            {
                Rect intersection = eyes[i] & eyes[j];
                if (intersection.area() > 0)
                {
                    eyes.erase(eyes.begin() + j);
                    if (i > j)
                        i--;
                    j--;
                }
            }
        }
    }

    if(eyes.size() > 2)
    {
        // finding the pair with lowest angle
        std::vector<std::pair<uint16_t, uint16_t>> helper;
        helper.reserve(eyes.size() * eyes.size() - eyes.size());
        for(auto i = eyes.begin(); i != eyes.end(); i++)
        {
            for(auto j = eyes.begin(); j != eyes.end(); j++)
            {
                if (i != j)
                    helper.push_back(std::make_pair(std::distance(eyes.begin(), i), std::distance(eyes.begin(), j)));
            }
        }

        std::sort(helper.begin(), helper.end(), [&eyes](const std::pair<uint16_t, uint16_t>& a, const std::pair<uint16_t, uint16_t>& b)
        {
            double angleA = std::abs(GetRotation(eyes[a.first], eyes[a.second]));
            double angleB = std::abs(GetRotation(eyes[b.first], eyes[b.second]));
            return angleA < angleB;
        });

        assert(helper.front().first != helper.front().second);

        std::swap(eyes[0], eyes[helper.front().first]);
        std::swap(eyes[1], eyes[helper.front().second]);
    }

    std::sort(eyes.begin(), eyes.begin() + 2, [](const Rect& a, const Rect& b) { return a.x < b.x; });
    eyes.resize(2);
    return eyes;
}

void FacePreprocessor::RotateFace()
{
    std::vector<Rect> eyes = GetEyes();
    if(eyes.size() < 2)
    {
        return;
    }

    double angle = GetRotation(eyes[0], eyes[1]);
    qDebug() << "rotation angle: " << angle;
    if (std::abs(angle) < std::numeric_limits<double>::epsilon() * 3 || std::abs(angle) > MAX_ROTATE_ANGLE)
        return;

    int size = std::max(result.cols, result.rows);
    int fullSize = std::max(normalized.cols, normalized.rows);
    Point2f pt(size/2.0f + face.x, size/2.0f + face.y);
    Mat r = getRotationMatrix2D(pt, angle, 1.0);

    warpAffine(normalized, rotated, r, Size(fullSize, fullSize), CV_INTER_LANCZOS4);

    result = rotated(face);
}

void FacePreprocessor::ScaleFace()
{
    Rect aspected = face;
    if(face.width < face.height)
    {
        aspected.width = face.height;
    }
    else
    {
        aspected.height = face.width;
    }

    Mat scaled = result.clone();

    copyMakeBorder(scaled, scaled, 0, aspected.height, 0, aspected.width, BORDER_REPLICATE);

    aspected.x = 0;
    aspected.y = 0;

    result = scaled(aspected);
    resize(result, result, Size(512, 512), 0.0, 0.0, CV_INTER_LANCZOS4);
}

double FacePreprocessor::GetAccuracy() const
{
    double accuracy = 0.0;
    if(face.width > 0 && face.height > 0)
        accuracy += 0.5;
    if(gotEyes)
        accuracy += 0.25;
    if(!rotated.empty())
        accuracy += 0.25;
    return accuracy;
}

Mat FacePreprocessor::Preprocess() throw (NoFaceFoundException)
{
    if(input.type() == CV_8UC3)
        cvtColor(input, result, CV_BGR2GRAY);
    else
        result = input;
    equalizeHist(result, normalized);

    result = normalized;

    std::vector<Rect> faces;
    Size minSize(GetMinSize(), GetMinSize());
    classifiers.face->detectMultiScale(result, faces, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT, minSize);

    if (!faces.empty())
    {
        face = LargestRect(faces);

        result = result(face);
    }
    else
    {
        throw NoFaceFoundException();
    }

    RotateFace();

    static uint64_t eyesFoundCntr = 0;
    static uint64_t totalRunCntr = 0;

    totalRunCntr++;

    if(!gotEyes)
        qDebug() << "no eyes were found on the face -- this is odd :(" << ++eyesFoundCntr << "/" << totalRunCntr;
    else
        qDebug() << "is rotated? " << !rotated.empty() << (totalRunCntr - eyesFoundCntr) << "/" << totalRunCntr;

    ScaleFace();

    return result;
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 - 2014, Adrian M. Partl <apartl@aip.de>,
 *                      eScience team AIP Potsdam
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  See the NOTICE file distributed with this work for additional
 *  information regarding copyright ownership. You may obtain a copy
 *  of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "AsciiDataObjDesc.h"
#include <math.h>
#include <string.h>
#include <iostream>
#include <assert.h>
#include <boost/algorithm/string/replace.hpp>

using namespace std;
using namespace DBDataSchema;

namespace AsciiIngest {

    AsciiDataObjDesc::AsciiDataObjDesc() {
        greedySep = 0;
    }

    AsciiDataObjDesc::~AsciiDataObjDesc() {

    }

    int AsciiDataObjDesc::getPrefixSkip() {
        return prefixSkip;
    }

    void AsciiDataObjDesc::setPrefixSkip(int newPrefixSkip) {
        assert(newPrefixSkip >= 0);

        prefixSkip = newPrefixSkip;
    }

    int AsciiDataObjDesc::getLenData() {
        return lenData;
    }

    void AsciiDataObjDesc::setLenData(int newLenData) {
        assert(newLenData >= 0);

        lenData = newLenData;
    }

    int AsciiDataObjDesc::getLineNum() {
        return lineNum;
    }

    void AsciiDataObjDesc::setLineNum(int newLineNum) {
        assert(newLineNum >= 0);

        lineNum = newLineNum;
    }

    char * AsciiDataObjDesc::getSep() {
        return sep;
    }

    void AsciiDataObjDesc::setSep(string newSep) {
        boost::replace_all(newSep, "\\n", "\n");
        boost::replace_all(newSep, "\\t", "\t");
        boost::replace_all(newSep, "\\r", "\r");
        boost::replace_all(newSep, "\\\\", "\\");
        boost::replace_all(newSep, "\\0", "\0");

        strncpy(sep, newSep.c_str(), 10);
    }

    void AsciiDataObjDesc::setGreedy(int newGreedy) {
        assert(newGreedy == 0 || newGreedy == 1);
        greedySep = newGreedy;
    }

    int AsciiDataObjDesc::getGreedy() {
        return greedySep;
    }

}<commit_msg>strncopy buffer size in AsciiDataObjDesc::setSep increased<commit_after>/*
 *  Copyright (c) 2012 - 2014, Adrian M. Partl <apartl@aip.de>,
 *                      eScience team AIP Potsdam
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  See the NOTICE file distributed with this work for additional
 *  information regarding copyright ownership. You may obtain a copy
 *  of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "AsciiDataObjDesc.h"
#include <math.h>
#include <string.h>
#include <iostream>
#include <assert.h>
#include <boost/algorithm/string/replace.hpp>

using namespace std;
using namespace DBDataSchema;

namespace AsciiIngest {

    AsciiDataObjDesc::AsciiDataObjDesc() {
        greedySep = 0;
    }

    AsciiDataObjDesc::~AsciiDataObjDesc() {

    }

    int AsciiDataObjDesc::getPrefixSkip() {
        return prefixSkip;
    }

    void AsciiDataObjDesc::setPrefixSkip(int newPrefixSkip) {
        assert(newPrefixSkip >= 0);

        prefixSkip = newPrefixSkip;
    }

    int AsciiDataObjDesc::getLenData() {
        return lenData;
    }

    void AsciiDataObjDesc::setLenData(int newLenData) {
        assert(newLenData >= 0);

        lenData = newLenData;
    }

    int AsciiDataObjDesc::getLineNum() {
        return lineNum;
    }

    void AsciiDataObjDesc::setLineNum(int newLineNum) {
        assert(newLineNum >= 0);

        lineNum = newLineNum;
    }

    char * AsciiDataObjDesc::getSep() {
        return sep;
    }

    void AsciiDataObjDesc::setSep(string newSep) {
        boost::replace_all(newSep, "\\n", "\n");
        boost::replace_all(newSep, "\\t", "\t");
        boost::replace_all(newSep, "\\r", "\r");
        boost::replace_all(newSep, "\\\\", "\\");
        boost::replace_all(newSep, "\\0", "\0");

        strncpy(sep, newSep.c_str(), 256);
    }

    void AsciiDataObjDesc::setGreedy(int newGreedy) {
        assert(newGreedy == 0 || newGreedy == 1);
        greedySep = newGreedy;
    }

    int AsciiDataObjDesc::getGreedy() {
        return greedySep;
    }

}<|endoftext|>


<commit_before>#pragma once

#include <list>
#include <unordered_map>
#include <vector>
#include <optional>
#include <mutex>
#include <functional>
#include <ostream>

namespace lru_cache
{
    namespace detail
    {
        /* Dummy replacement for mutex which defaults to cache with no thread safety */
        class nolocking
        {
        public:
            void lock() {}
            void unlock() {}
            bool try_lock() { return true; }
        };
    }

    /* Associative Least Recently Used (LRU) cache */
    template <typename Key_t, typename Value_t, typename Lock_t = detail::nolocking>
    class LRU_cache
    {
        static_assert(
            std::is_copy_constructible_v<Value_t>,
            "Cache requires copy-constructible objects, otherwise data access with get member function would pop the data out of the cache, which renders cache pointless.");

    protected:
        using List_t = std::list<std::pair<Key_t, Value_t>>;
        using Map_t = std::unordered_map<Key_t, typename List_t::iterator>;
        using Lock = std::lock_guard<Lock_t>;

        List_t  m_list;
        Map_t   m_map;
        const size_t  m_capacity;

        mutable Lock_t m_lock;

        std::function<void(Value_t)> m_onEvict;

        void evict()
        {
            auto lru = --m_list.end();

            if (m_onEvict)
            {
                m_onEvict(lru->second);
            }

            m_map.erase(lru->first);
            m_list.pop_back();
        }

    public:

        explicit LRU_cache(size_t capacity = 8)
            : m_list()
            , m_map(capacity)
            , m_capacity(capacity)
        {
        }

        virtual ~LRU_cache() = default;

        LRU_cache(const LRU_cache&) = delete;
        LRU_cache& operator=(const LRU_cache&) = delete;

        LRU_cache(LRU_cache&&) = default;
        LRU_cache& operator=(LRU_cache&&) = default;

        template <typename Func>
        void setOnEvictNotifier(Func callback)
        {
            static_assert(std::is_invocable_v<Func, Value_t>, "Invalid type, expected function or callable object, or object callable to be called with argument of type Value_t");
            m_onEvict = callback;
        }

        /*
         * Inserts an element (value) with the given key (key).
         * If a value with the fiven key exists, function does nothing.
         */
        template <
            typename Key_tt = Key_t,
            typename Value_tt = Value_t,
            class Key_tt_MustBe_Key_t = std::enable_if_t<std::is_same_v<std::remove_reference_t<Key_tt>, Key_t>>,
            class Value_tt_MustBe_Value_t = std::enable_if_t<std::is_same_v<std::remove_reference_t<Value_tt>, Value_t>>>
        void insert(Key_tt&& key, Value_tt&& value)
        {
            Lock lock(m_lock);

            // lookup value in cache
            auto it = m_map.find(key);
            if (it == m_map.end())
            {
                // insert item into cache (and check if cache is full)
                if (m_list.size() >= m_capacity)
                {
                    evict();
                }

                // insert element
                m_list.emplace_front(std::make_pair(key, std::forward<Value_tt>(value)));
                m_map[std::forward<Key_tt>(key)] = m_list.begin();
            }
        }

        /*
         * Retrieves the value by the given key (key).
         * If the given key isn't in cache, the function returns empty std::optional object.
         */
        template <typename Key_tt = Key_t,
            class TypeMustBe_Key_t = std::enable_if_t<std::is_same_v<std::remove_reference_t<Key_tt>, Key_t>>>
        std::optional<Value_t> get(Key_tt&& key)
        {
            Lock lock(m_lock);

            // look in the map if element is present
            auto it = m_map.find(key);
            // if not return the empty optional
            if (it == m_map.end())
            {
                return {};
            }

            // element is present...
            auto list_iterator = it->second;

            if (list_iterator == m_list.begin())
            {
                return { list_iterator->second };
            }
            else
            {
                // move the accessed element to front of the list
                m_list.splice(m_list.begin(), m_list, list_iterator);
                // and update hash map
                m_map[key] = m_list.begin();

                return { m_list.begin()->second };
            }
        }

        /*
         * Purges the cache
         */
        virtual void purge()
        {
            Lock lock(m_lock);

            m_list.clear();
            m_map.clear();
        }

        /*
         * Releases all key/value pairs into a vector and purges the cache.
         */
        virtual std::vector<std::pair<Key_t, Value_t>> release()
        {
            Lock lock(m_lock);

            std::vector<std::pair<Key_t, Value_t>> v;

            for (auto& pair : m_list)
            {
                v.emplace_back(std::move(pair));
            }

            purge();
            return v;
        }

        /*
         * Friend funtion for outputing key/value pairs.
         */
        friend std::ostream& operator<<(std::ostream& os, const LRU_cache& cache)
        {
            for (auto& pair : cache.m_list)
            {
                os << "Key: " << pair.first << "\tValue: " << pair.second << std::endl;
            }

            return os;
        }
    };
}
<commit_msg>Added licence into header file.<commit_after>/*********************************************************************************
 *
 *  MIT License
 *
 *  Copyright (c) 2017 Nenad Zikic
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in all
 *  copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *  SOFTWARE.
 *
 *********************************************************************************/

#pragma once

#include <list>
#include <unordered_map>
#include <vector>
#include <optional>
#include <mutex>
#include <functional>
#include <ostream>

namespace lru_cache
{
    namespace detail
    {
        /* Dummy replacement for mutex which defaults to cache with no thread safety */
        class nolocking
        {
        public:
            void lock() {}
            void unlock() {}
            bool try_lock() { return true; }
        };
    }

    /* Associative Least Recently Used (LRU) cache */
    template <typename Key_t, typename Value_t, typename Lock_t = detail::nolocking>
    class LRU_cache
    {
        static_assert(
            std::is_copy_constructible_v<Value_t>,
            "Cache requires copy-constructible objects, otherwise data access with get member function would pop the data out of the cache, which renders cache pointless.");

    protected:
        using List_t = std::list<std::pair<Key_t, Value_t>>;
        using Map_t = std::unordered_map<Key_t, typename List_t::iterator>;
        using Lock = std::lock_guard<Lock_t>;

        List_t  m_list;
        Map_t   m_map;
        const size_t  m_capacity;

        mutable Lock_t m_lock;

        std::function<void(Value_t)> m_onEvict;

        void evict()
        {
            auto lru = --m_list.end();

            if (m_onEvict)
            {
                m_onEvict(lru->second);
            }

            m_map.erase(lru->first);
            m_list.pop_back();
        }

    public:

        explicit LRU_cache(size_t capacity = 8)
            : m_list()
            , m_map(capacity)
            , m_capacity(capacity)
        {
        }

        virtual ~LRU_cache() = default;

        LRU_cache(const LRU_cache&) = delete;
        LRU_cache& operator=(const LRU_cache&) = delete;

        LRU_cache(LRU_cache&&) = default;
        LRU_cache& operator=(LRU_cache&&) = default;

        template <typename Func>
        void setOnEvictNotifier(Func callback)
        {
            static_assert(std::is_invocable_v<Func, Value_t>, "Invalid type, expected function or callable object, or object callable to be called with argument of type Value_t");
            m_onEvict = callback;
        }

        /*
         * Inserts an element (value) with the given key (key).
         * If a value with the fiven key exists, function does nothing.
         */
        template <
            typename Key_tt = Key_t,
            typename Value_tt = Value_t,
            class Key_tt_MustBe_Key_t = std::enable_if_t<std::is_same_v<std::remove_reference_t<Key_tt>, Key_t>>,
            class Value_tt_MustBe_Value_t = std::enable_if_t<std::is_same_v<std::remove_reference_t<Value_tt>, Value_t>>>
        void insert(Key_tt&& key, Value_tt&& value)
        {
            Lock lock(m_lock);

            // lookup value in cache
            auto it = m_map.find(key);
            if (it == m_map.end())
            {
                // insert item into cache (and check if cache is full)
                if (m_list.size() >= m_capacity)
                {
                    evict();
                }

                // insert element
                m_list.emplace_front(std::make_pair(key, std::forward<Value_tt>(value)));
                m_map[std::forward<Key_tt>(key)] = m_list.begin();
            }
        }

        /*
         * Retrieves the value by the given key (key).
         * If the given key isn't in cache, the function returns empty std::optional object.
         */
        template <typename Key_tt = Key_t,
            class TypeMustBe_Key_t = std::enable_if_t<std::is_same_v<std::remove_reference_t<Key_tt>, Key_t>>>
        std::optional<Value_t> get(Key_tt&& key)
        {
            Lock lock(m_lock);

            // look in the map if element is present
            auto it = m_map.find(key);
            // if not return the empty optional
            if (it == m_map.end())
            {
                return {};
            }

            // element is present...
            auto list_iterator = it->second;

            if (list_iterator == m_list.begin())
            {
                return { list_iterator->second };
            }
            else
            {
                // move the accessed element to front of the list
                m_list.splice(m_list.begin(), m_list, list_iterator);
                // and update hash map
                m_map[key] = m_list.begin();

                return { m_list.begin()->second };
            }
        }

        /*
         * Purges the cache
         */
        virtual void purge()
        {
            Lock lock(m_lock);

            m_list.clear();
            m_map.clear();
        }

        /*
         * Releases all key/value pairs into a vector and purges the cache.
         */
        virtual std::vector<std::pair<Key_t, Value_t>> release()
        {
            Lock lock(m_lock);

            std::vector<std::pair<Key_t, Value_t>> v;

            for (auto& pair : m_list)
            {
                v.emplace_back(std::move(pair));
            }

            purge();
            return v;
        }

        /*
         * Friend funtion for outputing key/value pairs.
         */
        friend std::ostream& operator<<(std::ostream& os, const LRU_cache& cache)
        {
            for (auto& pair : cache.m_list)
            {
                os << "Key: " << pair.first << "\tValue: " << pair.second << std::endl;
            }

            return os;
        }
    };
}
<|endoftext|>


<commit_before>//===--- FileRemapper.cpp - File Remapping Helper -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/ARCMigrate/FileRemapper.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Basic/FileManager.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <fstream>

using namespace clang;
using namespace arcmt;

FileRemapper::FileRemapper() {
  FileMgr.reset(new FileManager(FileSystemOptions()));
}

FileRemapper::~FileRemapper() {
  clear();
}

void FileRemapper::clear(StringRef outputDir) {
  for (MappingsTy::iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I)
    resetTarget(I->second);
  FromToMappings.clear();
  assert(ToFromMappings.empty());
  if (!outputDir.empty()) {
    std::string infoFile = getRemapInfoFile(outputDir);
    bool existed;
    llvm::sys::fs::remove(infoFile, existed);
  }
}

std::string FileRemapper::getRemapInfoFile(StringRef outputDir) {
  assert(!outputDir.empty());
  llvm::sys::Path dir(outputDir);
  llvm::sys::Path infoFile = dir;
  infoFile.appendComponent("remap");
  return infoFile.str();
}

bool FileRemapper::initFromDisk(StringRef outputDir, Diagnostic &Diag,
                                bool ignoreIfFilesChanged) {
  assert(FromToMappings.empty() &&
         "initFromDisk should be called before any remap calls");
  std::string infoFile = getRemapInfoFile(outputDir);
  bool fileExists = false;
  llvm::sys::fs::exists(infoFile, fileExists);
  if (!fileExists)
    return false;

  std::vector<std::pair<const FileEntry *, const FileEntry *> > pairs;

  llvm::OwningPtr<llvm::MemoryBuffer> fileBuf;
  if (llvm::error_code ec = llvm::MemoryBuffer::getFile(infoFile.c_str(),
                                                        fileBuf))
    return report(std::string("Error opening file: ") + infoFile, Diag);

  SmallVector<StringRef, 64> lines;
  fileBuf->getBuffer().split(lines, "\n");

  for (unsigned idx = 0; idx+3 <= lines.size(); idx += 3) {
    std::string fromFilename = lines[idx];
    uint64_t timeModified;
    lines[idx+1].getAsInteger(10, timeModified);
    std::string toFilename = lines[idx+2];

    const FileEntry *origFE = FileMgr->getFile(fromFilename);
    if (!origFE) {
      if (ignoreIfFilesChanged)
        continue;
      return report(std::string("File does not exist: ") + fromFilename, Diag);
    }
    const FileEntry *newFE = FileMgr->getFile(toFilename);
    if (!newFE) {
      if (ignoreIfFilesChanged)
        continue;
      return report(std::string("File does not exist: ") + toFilename, Diag);
    }

    if ((uint64_t)origFE->getModificationTime() != timeModified) {
      if (ignoreIfFilesChanged)
        continue;
      return report(std::string("File was modified: ") + fromFilename, Diag);
    }

    pairs.push_back(std::make_pair(origFE, newFE));
  }

  for (unsigned i = 0, e = pairs.size(); i != e; ++i)
    remap(pairs[i].first, pairs[i].second);

  return false;
}

bool FileRemapper::flushToDisk(StringRef outputDir, Diagnostic &Diag) {
  using namespace llvm::sys;

  bool existed;
  if (fs::create_directory(outputDir, existed) != llvm::errc::success)
    return report(std::string("Could not create directory: ") + outputDir.str(),
                  Diag);

  std::string errMsg;
  std::string infoFile = getRemapInfoFile(outputDir);
  llvm::raw_fd_ostream infoOut(infoFile.c_str(), errMsg,
                               llvm::raw_fd_ostream::F_Binary);
  if (!errMsg.empty())
    return report(errMsg, Diag);

  for (MappingsTy::iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {

    const FileEntry *origFE = I->first;
    llvm::SmallString<200> origPath = StringRef(origFE->getName());
    fs::make_absolute(origPath);
    infoOut << origPath << '\n';
    infoOut << (uint64_t)origFE->getModificationTime() << '\n';

    if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
      llvm::SmallString<200> newPath = StringRef(FE->getName());
      fs::make_absolute(newPath);
      infoOut << newPath << '\n';
    } else {

      llvm::SmallString<64> tempPath;
      tempPath = path::filename(origFE->getName());
      tempPath += "-%%%%%%%%";
      tempPath += path::extension(origFE->getName());
      int fd;
      if (fs::unique_file(tempPath.str(), fd, tempPath) != llvm::errc::success)
        return report(std::string("Could not create file: ") + tempPath.c_str(),
                      Diag);

      llvm::raw_fd_ostream newOut(fd, /*shouldClose=*/true);
      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
      newOut.write(mem->getBufferStart(), mem->getBufferSize());
      newOut.close();

      const FileEntry *newE = FileMgr->getFile(tempPath);
      remap(origFE, newE);
      infoOut << newE->getName() << '\n';
    }
  }

  infoOut.close();
  return false;
}

bool FileRemapper::overwriteOriginal(Diagnostic &Diag,
                                     StringRef outputDir) {
  using namespace llvm::sys;

  for (MappingsTy::iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
    const FileEntry *origFE = I->first;
    if (const FileEntry *newFE = I->second.dyn_cast<const FileEntry *>()) {
      if (fs::copy_file(newFE->getName(), origFE->getName(),
                 fs::copy_option::overwrite_if_exists) != llvm::errc::success) {
        std::string err = "Could not copy file '";
        llvm::raw_string_ostream os(err);
        os << "Could not copy file '" << newFE->getName() << "' to file '"
           << origFE->getName() << "'";
        os.flush();
        return report(err, Diag);
      }
    } else {

      bool fileExists = false;
      fs::exists(origFE->getName(), fileExists);
      if (!fileExists)
        return report(std::string("File does not exist: ") + origFE->getName(),
                      Diag);

      std::string errMsg;
      llvm::raw_fd_ostream Out(origFE->getName(), errMsg,
                               llvm::raw_fd_ostream::F_Binary);
      if (!errMsg.empty())
        return report(errMsg, Diag);

      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
      Out.write(mem->getBufferStart(), mem->getBufferSize());
      Out.close();
    }
  }

  clear(outputDir);
  return false;
}

void FileRemapper::applyMappings(CompilerInvocation &CI) const {
  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
  for (MappingsTy::const_iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
    if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
      PPOpts.addRemappedFile(I->first->getName(), FE->getName());
    } else {
      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
      PPOpts.addRemappedFile(I->first->getName(), mem);
    }
  }

  PPOpts.RetainRemappedFileBuffers = true;
}

void FileRemapper::transferMappingsAndClear(CompilerInvocation &CI) {
  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
  for (MappingsTy::iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
    if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
      PPOpts.addRemappedFile(I->first->getName(), FE->getName());
    } else {
      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
      PPOpts.addRemappedFile(I->first->getName(), mem);
    }
    I->second = Target();
  }

  PPOpts.RetainRemappedFileBuffers = false;
  clear();
}

void FileRemapper::remap(StringRef filePath, llvm::MemoryBuffer *memBuf) {
  remap(getOriginalFile(filePath), memBuf);
}

void FileRemapper::remap(StringRef filePath, StringRef newPath) {
  const FileEntry *file = getOriginalFile(filePath);
  const FileEntry *newfile = FileMgr->getFile(newPath);
  remap(file, newfile);
}

void FileRemapper::remap(const FileEntry *file, llvm::MemoryBuffer *memBuf) {
  assert(file);
  Target &targ = FromToMappings[file];
  resetTarget(targ);
  targ = memBuf;
}

void FileRemapper::remap(const FileEntry *file, const FileEntry *newfile) {
  assert(file && newfile);
  Target &targ = FromToMappings[file];
  resetTarget(targ);
  targ = newfile;
  ToFromMappings[newfile] = file;
}

const FileEntry *FileRemapper::getOriginalFile(StringRef filePath) {
  const FileEntry *file = FileMgr->getFile(filePath);
  // If we are updating a file that overriden an original file,
  // actually update the original file.
  llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
    I = ToFromMappings.find(file);
  if (I != ToFromMappings.end()) {
    file = I->second;
    assert(FromToMappings.find(file) != FromToMappings.end() &&
           "Original file not in mappings!");
  }
  return file;
}

void FileRemapper::resetTarget(Target &targ) {
  if (!targ)
    return;

  if (llvm::MemoryBuffer *oldmem = targ.dyn_cast<llvm::MemoryBuffer *>()) {
    delete oldmem;
  } else {
    const FileEntry *toFE = targ.get<const FileEntry *>();
    llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
      I = ToFromMappings.find(toFE);
    if (I != ToFromMappings.end())
      ToFromMappings.erase(I);
  }
}

bool FileRemapper::report(const std::string &err, Diagnostic &Diag) {
  unsigned ID = Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Error,
                                                         err);
  Diag.Report(ID);
  return true;
}
<commit_msg>Try to unbreak the build on systems where uint64_t isn't something that StringRef::getAsInteger can handle as its second argument<commit_after>//===--- FileRemapper.cpp - File Remapping Helper -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/ARCMigrate/FileRemapper.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Basic/FileManager.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <fstream>

using namespace clang;
using namespace arcmt;

FileRemapper::FileRemapper() {
  FileMgr.reset(new FileManager(FileSystemOptions()));
}

FileRemapper::~FileRemapper() {
  clear();
}

void FileRemapper::clear(StringRef outputDir) {
  for (MappingsTy::iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I)
    resetTarget(I->second);
  FromToMappings.clear();
  assert(ToFromMappings.empty());
  if (!outputDir.empty()) {
    std::string infoFile = getRemapInfoFile(outputDir);
    bool existed;
    llvm::sys::fs::remove(infoFile, existed);
  }
}

std::string FileRemapper::getRemapInfoFile(StringRef outputDir) {
  assert(!outputDir.empty());
  llvm::sys::Path dir(outputDir);
  llvm::sys::Path infoFile = dir;
  infoFile.appendComponent("remap");
  return infoFile.str();
}

bool FileRemapper::initFromDisk(StringRef outputDir, Diagnostic &Diag,
                                bool ignoreIfFilesChanged) {
  assert(FromToMappings.empty() &&
         "initFromDisk should be called before any remap calls");
  std::string infoFile = getRemapInfoFile(outputDir);
  bool fileExists = false;
  llvm::sys::fs::exists(infoFile, fileExists);
  if (!fileExists)
    return false;

  std::vector<std::pair<const FileEntry *, const FileEntry *> > pairs;

  llvm::OwningPtr<llvm::MemoryBuffer> fileBuf;
  if (llvm::error_code ec = llvm::MemoryBuffer::getFile(infoFile.c_str(),
                                                        fileBuf))
    return report(std::string("Error opening file: ") + infoFile, Diag);

  SmallVector<StringRef, 64> lines;
  fileBuf->getBuffer().split(lines, "\n");

  for (unsigned idx = 0; idx+3 <= lines.size(); idx += 3) {
    std::string fromFilename = lines[idx];
    unsigned long long timeModified;
    lines[idx+1].getAsInteger(10, timeModified);
    std::string toFilename = lines[idx+2];

    const FileEntry *origFE = FileMgr->getFile(fromFilename);
    if (!origFE) {
      if (ignoreIfFilesChanged)
        continue;
      return report(std::string("File does not exist: ") + fromFilename, Diag);
    }
    const FileEntry *newFE = FileMgr->getFile(toFilename);
    if (!newFE) {
      if (ignoreIfFilesChanged)
        continue;
      return report(std::string("File does not exist: ") + toFilename, Diag);
    }

    if ((uint64_t)origFE->getModificationTime() != timeModified) {
      if (ignoreIfFilesChanged)
        continue;
      return report(std::string("File was modified: ") + fromFilename, Diag);
    }

    pairs.push_back(std::make_pair(origFE, newFE));
  }

  for (unsigned i = 0, e = pairs.size(); i != e; ++i)
    remap(pairs[i].first, pairs[i].second);

  return false;
}

bool FileRemapper::flushToDisk(StringRef outputDir, Diagnostic &Diag) {
  using namespace llvm::sys;

  bool existed;
  if (fs::create_directory(outputDir, existed) != llvm::errc::success)
    return report(std::string("Could not create directory: ") + outputDir.str(),
                  Diag);

  std::string errMsg;
  std::string infoFile = getRemapInfoFile(outputDir);
  llvm::raw_fd_ostream infoOut(infoFile.c_str(), errMsg,
                               llvm::raw_fd_ostream::F_Binary);
  if (!errMsg.empty())
    return report(errMsg, Diag);

  for (MappingsTy::iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {

    const FileEntry *origFE = I->first;
    llvm::SmallString<200> origPath = StringRef(origFE->getName());
    fs::make_absolute(origPath);
    infoOut << origPath << '\n';
    infoOut << (uint64_t)origFE->getModificationTime() << '\n';

    if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
      llvm::SmallString<200> newPath = StringRef(FE->getName());
      fs::make_absolute(newPath);
      infoOut << newPath << '\n';
    } else {

      llvm::SmallString<64> tempPath;
      tempPath = path::filename(origFE->getName());
      tempPath += "-%%%%%%%%";
      tempPath += path::extension(origFE->getName());
      int fd;
      if (fs::unique_file(tempPath.str(), fd, tempPath) != llvm::errc::success)
        return report(std::string("Could not create file: ") + tempPath.c_str(),
                      Diag);

      llvm::raw_fd_ostream newOut(fd, /*shouldClose=*/true);
      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
      newOut.write(mem->getBufferStart(), mem->getBufferSize());
      newOut.close();

      const FileEntry *newE = FileMgr->getFile(tempPath);
      remap(origFE, newE);
      infoOut << newE->getName() << '\n';
    }
  }

  infoOut.close();
  return false;
}

bool FileRemapper::overwriteOriginal(Diagnostic &Diag,
                                     StringRef outputDir) {
  using namespace llvm::sys;

  for (MappingsTy::iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
    const FileEntry *origFE = I->first;
    if (const FileEntry *newFE = I->second.dyn_cast<const FileEntry *>()) {
      if (fs::copy_file(newFE->getName(), origFE->getName(),
                 fs::copy_option::overwrite_if_exists) != llvm::errc::success) {
        std::string err = "Could not copy file '";
        llvm::raw_string_ostream os(err);
        os << "Could not copy file '" << newFE->getName() << "' to file '"
           << origFE->getName() << "'";
        os.flush();
        return report(err, Diag);
      }
    } else {

      bool fileExists = false;
      fs::exists(origFE->getName(), fileExists);
      if (!fileExists)
        return report(std::string("File does not exist: ") + origFE->getName(),
                      Diag);

      std::string errMsg;
      llvm::raw_fd_ostream Out(origFE->getName(), errMsg,
                               llvm::raw_fd_ostream::F_Binary);
      if (!errMsg.empty())
        return report(errMsg, Diag);

      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
      Out.write(mem->getBufferStart(), mem->getBufferSize());
      Out.close();
    }
  }

  clear(outputDir);
  return false;
}

void FileRemapper::applyMappings(CompilerInvocation &CI) const {
  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
  for (MappingsTy::const_iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
    if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
      PPOpts.addRemappedFile(I->first->getName(), FE->getName());
    } else {
      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
      PPOpts.addRemappedFile(I->first->getName(), mem);
    }
  }

  PPOpts.RetainRemappedFileBuffers = true;
}

void FileRemapper::transferMappingsAndClear(CompilerInvocation &CI) {
  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
  for (MappingsTy::iterator
         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
    if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
      PPOpts.addRemappedFile(I->first->getName(), FE->getName());
    } else {
      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
      PPOpts.addRemappedFile(I->first->getName(), mem);
    }
    I->second = Target();
  }

  PPOpts.RetainRemappedFileBuffers = false;
  clear();
}

void FileRemapper::remap(StringRef filePath, llvm::MemoryBuffer *memBuf) {
  remap(getOriginalFile(filePath), memBuf);
}

void FileRemapper::remap(StringRef filePath, StringRef newPath) {
  const FileEntry *file = getOriginalFile(filePath);
  const FileEntry *newfile = FileMgr->getFile(newPath);
  remap(file, newfile);
}

void FileRemapper::remap(const FileEntry *file, llvm::MemoryBuffer *memBuf) {
  assert(file);
  Target &targ = FromToMappings[file];
  resetTarget(targ);
  targ = memBuf;
}

void FileRemapper::remap(const FileEntry *file, const FileEntry *newfile) {
  assert(file && newfile);
  Target &targ = FromToMappings[file];
  resetTarget(targ);
  targ = newfile;
  ToFromMappings[newfile] = file;
}

const FileEntry *FileRemapper::getOriginalFile(StringRef filePath) {
  const FileEntry *file = FileMgr->getFile(filePath);
  // If we are updating a file that overriden an original file,
  // actually update the original file.
  llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
    I = ToFromMappings.find(file);
  if (I != ToFromMappings.end()) {
    file = I->second;
    assert(FromToMappings.find(file) != FromToMappings.end() &&
           "Original file not in mappings!");
  }
  return file;
}

void FileRemapper::resetTarget(Target &targ) {
  if (!targ)
    return;

  if (llvm::MemoryBuffer *oldmem = targ.dyn_cast<llvm::MemoryBuffer *>()) {
    delete oldmem;
  } else {
    const FileEntry *toFE = targ.get<const FileEntry *>();
    llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
      I = ToFromMappings.find(toFE);
    if (I != ToFromMappings.end())
      ToFromMappings.erase(I);
  }
}

bool FileRemapper::report(const std::string &err, Diagnostic &Diag) {
  unsigned ID = Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Error,
                                                         err);
  Diag.Report(ID);
  return true;
}
<|endoftext|>


<commit_before>//===- MachineLoopInfo.cpp - Natural Loop Calculator ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MachineLoopInfo class that is used to identify natural
// loops and determine the loop depth of various nodes of the CFG.  Note that
// the loops identified may actually be several natural loops that share the
// same header node... not just a single natural loop.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/Passes.h"

using namespace llvm;

TEMPLATE_INSTANTIATION(class LoopBase<MachineBasicBlock>);
TEMPLATE_INSTANTIATION(class LoopInfoBase<MachineBasicBlock>);

namespace {
  char MachineLoopInfo::ID = 0;
  RegisterPass<MachineLoopInfo>
  X("machine-loops", "Machine Natural Loop Construction", true);
}

const PassInfo *llvm::MachineLoopInfoID = X.getPassInfo();

bool MachineLoopInfo::runOnMachineFunction(MachineFunction &) {
  releaseMemory();
  LI->Calculate(getAnalysis<MachineDominatorTree>().getBase());    // Update
  return false;
}

void MachineLoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<MachineDominatorTree>();
}

// Ensure this file gets linked when MachineLoopInfo.h is used.
DEFINING_FILE_FOR(MachineLoopInfo)
<commit_msg>make this build with newer gcc's<commit_after>//===- MachineLoopInfo.cpp - Natural Loop Calculator ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MachineLoopInfo class that is used to identify natural
// loops and determine the loop depth of various nodes of the CFG.  Note that
// the loops identified may actually be several natural loops that share the
// same header node... not just a single natural loop.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/Passes.h"
using namespace llvm;

TEMPLATE_INSTANTIATION(class LoopBase<MachineBasicBlock>);
TEMPLATE_INSTANTIATION(class LoopInfoBase<MachineBasicBlock>);

char MachineLoopInfo::ID = 0;
namespace {
  RegisterPass<MachineLoopInfo>
  X("machine-loops", "Machine Natural Loop Construction", true);
}

const PassInfo *llvm::MachineLoopInfoID = X.getPassInfo();

bool MachineLoopInfo::runOnMachineFunction(MachineFunction &) {
  releaseMemory();
  LI->Calculate(getAnalysis<MachineDominatorTree>().getBase());    // Update
  return false;
}

void MachineLoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<MachineDominatorTree>();
}

// Ensure this file gets linked when MachineLoopInfo.h is used.
DEFINING_FILE_FOR(MachineLoopInfo)
<|endoftext|>


<commit_before>#include "iconv.h"

#include <v8.h>
#include <node.h>
#include <node_buffer.h>

#include <cstring>
#include <cerrno>

using namespace v8;
using namespace node;

namespace {

class Iconv: public ObjectWrap {
public:
  static void Initialize(Handle<Object>& target);
  static Handle<Value> New(const Arguments& args);
  static Handle<Value> Convert(const Arguments& args);

  Iconv(iconv_t conv);
  ~Iconv(); // destructor may not run if program is short-lived or aborted

  // the actual conversion happens here
  Handle<Value> Convert(char* data, size_t length);

private:
  iconv_t conv_;
};

Iconv::Iconv(iconv_t conv): conv_(conv) {
  assert(conv_ != (iconv_t) -1);
}

Iconv::~Iconv() {
  ::iconv_close(conv_);
}

// helper class: reverse linked list of dumb buffers
struct chunk {
  chunk *const prev;
  size_t size;
  char data[32 * 1024];

  chunk(chunk *prev): prev(prev), size(0) {
  }
};

// the actual conversion happens here
Handle<Value> Iconv::Convert(char* data, size_t length) {
  assert(conv_ != (iconv_t) -1);
  assert(data != 0);

  chunk *c = 0;
  char *inbuf = data;
  size_t inbytesleft = length;
  size_t offset = 0;

  while (true) {
    c = new chunk(c);

    char *outbuf = c->data;
    size_t outbytesleft = sizeof(c->data);

    size_t rv = ::iconv(conv_, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
    c->size = sizeof(c->data) - outbytesleft;
    offset += c->size;

    if (rv == (size_t) -1) {
      if (errno == E2BIG) {
        continue;
      }
      if (errno == EINVAL) {
        return ThrowException(ErrnoException(errno, "iconv", "Incomplete character sequence."));
      }
      if (errno == EILSEQ) {
        return ThrowException(ErrnoException(errno, "iconv", "Illegal character sequence."));
      }
      return ThrowException(ErrnoException(errno, "iconv"));
    }

    assert(inbytesleft == 0);
    break;
  }

  // copy linked list of chunks into Buffer in reverse order (last chunk at the top, second-to-last chunk below that, etc)
  Buffer& b = *Buffer::New(offset);
  for (chunk *t; c != 0; t = c->prev, delete c, c = t) {
    offset -= c->size;
    memcpy(b.data() + offset, c->data, c->size);
  }

  return b.handle_;
}

Handle<Value> Iconv::Convert(const Arguments& args) {
  HandleScope scope;

  Iconv* self = ObjectWrap::Unwrap<Iconv>(args.This());
  Local<Value> arg = args[0];

  if (arg->IsString()) {
    String::Utf8Value string(arg->ToString());
    return self->Convert(*string, string.length());
  }

  if (arg->IsObject()) {
    Local<Object> object = arg->ToObject();
    if (Buffer::HasInstance(object)) {
      Buffer& buffer = *ObjectWrap::Unwrap<Buffer>(object);
      return self->Convert(buffer.data(), buffer.length());
    }
  }

  return Undefined();
}

Handle<Value> Iconv::New(const Arguments& args) {
  HandleScope scope;

  // inconsistency: node-iconv expects (source, target) while native iconv expects (target, source)
  // wontfix for now, node-iconv's approach feels more intuitive
  String::AsciiValue sourceEncoding(args[0]->ToString());
  String::AsciiValue targetEncoding(args[1]->ToString());

  iconv_t conv = ::iconv_open(*targetEncoding, *sourceEncoding);
  if (conv == (iconv_t) -1) {
    return ThrowException(ErrnoException(errno, "iconv_open", "Conversion not supported."));
  }

  Iconv* instance = new Iconv(conv);
  instance->Wrap(args.Holder());

  return args.This();
}

void Iconv::Initialize(Handle<Object>& target) {
  HandleScope scope;

  Local<FunctionTemplate> t = FunctionTemplate::New(Iconv::New);
  t->InstanceTemplate()->SetInternalFieldCount(1);

  NODE_SET_PROTOTYPE_METHOD(t, "convert", Iconv::Convert);

  target->Set(String::NewSymbol("Iconv"), t->GetFunction());
}

extern "C" void init(Handle<Object> target) {
  Iconv::Initialize(target);
}

} // namespace
<commit_msg>Change indentation from two spaces to a single tab. The former may be the node.js convention but the latter is easier to read.<commit_after>#include "iconv.h"

#include <v8.h>
#include <node.h>
#include <node_buffer.h>

#include <cstring>
#include <cerrno>

using namespace v8;
using namespace node;

namespace {

class Iconv: public ObjectWrap {
public:
	static void Initialize(Handle<Object>& target);
	static Handle<Value> New(const Arguments& args);
	static Handle<Value> Convert(const Arguments& args);

	Iconv(iconv_t conv);
	~Iconv(); // destructor may not run if program is short-lived or aborted

	// the actual conversion happens here
	Handle<Value> Convert(char* data, size_t length);

private:
	iconv_t conv_;
};

Iconv::Iconv(iconv_t conv): conv_(conv) {
	assert(conv_ != (iconv_t) -1);
}

Iconv::~Iconv() {
	::iconv_close(conv_);
}

// helper class: reverse linked list of dumb buffers
struct chunk {
	chunk *const prev;
	size_t size;
	char data[32 * 1024];

	chunk(chunk *prev): prev(prev), size(0) {
	}
};

// the actual conversion happens here
Handle<Value> Iconv::Convert(char* data, size_t length) {
	assert(conv_ != (iconv_t) -1);
	assert(data != 0);

	chunk *c = 0;
	char *inbuf = data;
	size_t inbytesleft = length;
	size_t offset = 0;

	while (true) {
		c = new chunk(c);

		char *outbuf = c->data;
		size_t outbytesleft = sizeof(c->data);

		size_t rv = ::iconv(conv_, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
		c->size = sizeof(c->data) - outbytesleft;
		offset += c->size;

		if (rv == (size_t) -1) {
			if (errno == E2BIG) {
				continue;
			}
			if (errno == EINVAL) {
				return ThrowException(ErrnoException(errno, "iconv", "Incomplete character sequence."));
			}
			if (errno == EILSEQ) {
				return ThrowException(ErrnoException(errno, "iconv", "Illegal character sequence."));
			}
			return ThrowException(ErrnoException(errno, "iconv"));
		}

		assert(inbytesleft == 0);
		break;
	}

	// copy linked list of chunks into Buffer in reverse order (last chunk at the top, second-to-last chunk below that, etc)
	Buffer& b = *Buffer::New(offset);
	for (chunk *t; c != 0; t = c->prev, delete c, c = t) {
		offset -= c->size;
		memcpy(b.data() + offset, c->data, c->size);
	}

	return b.handle_;
}

Handle<Value> Iconv::Convert(const Arguments& args) {
	HandleScope scope;

	Iconv* self = ObjectWrap::Unwrap<Iconv>(args.This());
	Local<Value> arg = args[0];

	if (arg->IsString()) {
		String::Utf8Value string(arg->ToString());
		return self->Convert(*string, string.length());
	}

	if (arg->IsObject()) {
		Local<Object> object = arg->ToObject();
		if (Buffer::HasInstance(object)) {
			Buffer& buffer = *ObjectWrap::Unwrap<Buffer>(object);
			return self->Convert(buffer.data(), buffer.length());
		}
	}

	return Undefined();
}

Handle<Value> Iconv::New(const Arguments& args) {
	HandleScope scope;

	// inconsistency: node-iconv expects (source, target) while native iconv expects (target, source)
	// wontfix for now, node-iconv's approach feels more intuitive
	String::AsciiValue sourceEncoding(args[0]->ToString());
	String::AsciiValue targetEncoding(args[1]->ToString());

	iconv_t conv = ::iconv_open(*targetEncoding, *sourceEncoding);
	if (conv == (iconv_t) -1) {
		return ThrowException(ErrnoException(errno, "iconv_open", "Conversion not supported."));
	}

	Iconv* instance = new Iconv(conv);
	instance->Wrap(args.Holder());

	return args.This();
}

void Iconv::Initialize(Handle<Object>& target) {
	HandleScope scope;

	Local<FunctionTemplate> t = FunctionTemplate::New(Iconv::New);
	t->InstanceTemplate()->SetInternalFieldCount(1);

	NODE_SET_PROTOTYPE_METHOD(t, "convert", Iconv::Convert);

	target->Set(String::NewSymbol("Iconv"), t->GetFunction());
}

extern "C" void init(Handle<Object> target) {
	Iconv::Initialize(target);
}

} // namespace
<|endoftext|>


<commit_before>//===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "ToolChains.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Path.h"

// Include the necessary headers to interface with the Windows registry and
// environment.
#if defined(LLVM_ON_WIN32)
#define USE_WIN32
#endif

#ifdef USE_WIN32
  #define WIN32_LEAN_AND_MEAN
  #define NOGDI
  #define NOMINMAX
  #include <windows.h>
#endif

using namespace clang::driver;
using namespace clang::driver::toolchains;
using namespace clang;
using namespace llvm::opt;

Windows::Windows(const Driver &D, const llvm::Triple& Triple,
                 const ArgList &Args)
  : ToolChain(D, Triple, Args) {
}

Tool *Windows::buildLinker() const {
  return new tools::visualstudio::Link(*this);
}

Tool *Windows::buildAssembler() const {
  if (getTriple().isOSBinFormatMachO())
    return new tools::darwin::Assemble(*this);
  getDriver().Diag(clang::diag::err_no_external_assembler);
  return nullptr;
}

bool Windows::IsIntegratedAssemblerDefault() const {
  return true;
}

bool Windows::IsUnwindTablesDefault() const {
  return getArch() == llvm::Triple::x86_64;
}

bool Windows::isPICDefault() const {
  return getArch() == llvm::Triple::x86_64;
}

bool Windows::isPIEDefault() const {
  return false;
}

bool Windows::isPICDefaultForced() const {
  return getArch() == llvm::Triple::x86_64;
}

/// \brief Read registry string.
/// This also supports a means to look for high-versioned keys by use
/// of a $VERSION placeholder in the key path.
/// $VERSION in the key path is a placeholder for the version number,
/// causing the highest value path to be searched for and used.
/// I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
/// There can be additional characters in the component.  Only the numberic
/// characters are compared.
static bool getSystemRegistryString(const char *keyPath, const char *valueName,
                                    char *value, size_t maxLength) {
#ifndef USE_WIN32
  return false;
#else
  HKEY hRootKey = NULL;
  HKEY hKey = NULL;
  const char* subKey = NULL;
  DWORD valueType;
  DWORD valueSize = maxLength - 1;
  long lResult;
  bool returnValue = false;

  if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
    hRootKey = HKEY_CLASSES_ROOT;
    subKey = keyPath + 18;
  } else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) {
    hRootKey = HKEY_USERS;
    subKey = keyPath + 11;
  } else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) {
    hRootKey = HKEY_LOCAL_MACHINE;
    subKey = keyPath + 19;
  } else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) {
    hRootKey = HKEY_CURRENT_USER;
    subKey = keyPath + 18;
  } else {
    return false;
  }

  const char *placeHolder = strstr(subKey, "$VERSION");
  char bestName[256];
  bestName[0] = '\0';
  // If we have a $VERSION placeholder, do the highest-version search.
  if (placeHolder) {
    const char *keyEnd = placeHolder - 1;
    const char *nextKey = placeHolder;
    // Find end of previous key.
    while ((keyEnd > subKey) && (*keyEnd != '\\'))
      keyEnd--;
    // Find end of key containing $VERSION.
    while (*nextKey && (*nextKey != '\\'))
      nextKey++;
    size_t partialKeyLength = keyEnd - subKey;
    char partialKey[256];
    if (partialKeyLength > sizeof(partialKey))
      partialKeyLength = sizeof(partialKey);
    strncpy(partialKey, subKey, partialKeyLength);
    partialKey[partialKeyLength] = '\0';
    HKEY hTopKey = NULL;
    lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
                           &hTopKey);
    if (lResult == ERROR_SUCCESS) {
      char keyName[256];
      int bestIndex = -1;
      double bestValue = 0.0;
      DWORD index, size = sizeof(keyName) - 1;
      for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
          NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
        const char *sp = keyName;
        while (*sp && !isDigit(*sp))
          sp++;
        if (!*sp)
          continue;
        const char *ep = sp + 1;
        while (*ep && (isDigit(*ep) || (*ep == '.')))
          ep++;
        char numBuf[32];
        strncpy(numBuf, sp, sizeof(numBuf) - 1);
        numBuf[sizeof(numBuf) - 1] = '\0';
        double dvalue = strtod(numBuf, NULL);
        if (dvalue > bestValue) {
          // Test that InstallDir is indeed there before keeping this index.
          // Open the chosen key path remainder.
          strcpy(bestName, keyName);
          // Append rest of key.
          strncat(bestName, nextKey, sizeof(bestName) - 1);
          bestName[sizeof(bestName) - 1] = '\0';
          lResult = RegOpenKeyEx(hTopKey, bestName, 0,
                                 KEY_READ | KEY_WOW64_32KEY, &hKey);
          if (lResult == ERROR_SUCCESS) {
            lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
              (LPBYTE)value, &valueSize);
            if (lResult == ERROR_SUCCESS) {
              bestIndex = (int)index;
              bestValue = dvalue;
              returnValue = true;
            }
            RegCloseKey(hKey);
          }
        }
        size = sizeof(keyName) - 1;
      }
      RegCloseKey(hTopKey);
    }
  } else {
    lResult = RegOpenKeyEx(hRootKey, subKey, 0, KEY_READ | KEY_WOW64_32KEY,
                           &hKey);
    if (lResult == ERROR_SUCCESS) {
      lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
        (LPBYTE)value, &valueSize);
      if (lResult == ERROR_SUCCESS)
        returnValue = true;
      RegCloseKey(hKey);
    }
  }
  return returnValue;
#endif // USE_WIN32
}

/// \brief Get Windows SDK installation directory.
static bool getWindowsSDKDir(std::string &path) {
  char windowsSDKInstallDir[256];
  // Try the Windows registry.
  bool hasSDKDir = getSystemRegistryString(
   "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
                                           "InstallationFolder",
                                           windowsSDKInstallDir,
                                           sizeof(windowsSDKInstallDir) - 1);
    // If we have both vc80 and vc90, pick version we were compiled with.
  if (hasSDKDir && windowsSDKInstallDir[0]) {
    path = windowsSDKInstallDir;
    return true;
  }
  return false;
}

// Get Visual Studio installation directory.
static bool getVisualStudioDir(std::string &path) {
  // First check the environment variables that vsvars32.bat sets.
  const char* vcinstalldir = getenv("VCINSTALLDIR");
  if (vcinstalldir) {
    char *p = const_cast<char *>(strstr(vcinstalldir, "\\VC"));
    if (p)
      *p = '\0';
    path = vcinstalldir;
    return true;
  }

  char vsIDEInstallDir[256];
  char vsExpressIDEInstallDir[256];
  // Then try the windows registry.
  bool hasVCDir = getSystemRegistryString(
    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
    "InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1);
  bool hasVCExpressDir = getSystemRegistryString(
    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
    "InstallDir", vsExpressIDEInstallDir, sizeof(vsExpressIDEInstallDir) - 1);
    // If we have both vc80 and vc90, pick version we were compiled with.
  if (hasVCDir && vsIDEInstallDir[0]) {
    char *p = (char*)strstr(vsIDEInstallDir, "\\Common7\\IDE");
    if (p)
      *p = '\0';
    path = vsIDEInstallDir;
    return true;
  }

  if (hasVCExpressDir && vsExpressIDEInstallDir[0]) {
    char *p = (char*)strstr(vsExpressIDEInstallDir, "\\Common7\\IDE");
    if (p)
      *p = '\0';
    path = vsExpressIDEInstallDir;
    return true;
  }

  // Try the environment.
  const char *vs100comntools = getenv("VS100COMNTOOLS");
  const char *vs90comntools = getenv("VS90COMNTOOLS");
  const char *vs80comntools = getenv("VS80COMNTOOLS");

  const char *vscomntools = nullptr;

  // Find any version we can
  if (vs100comntools)
    vscomntools = vs100comntools;
  else if (vs90comntools)
    vscomntools = vs90comntools;
  else if (vs80comntools)
    vscomntools = vs80comntools;

  if (vscomntools && *vscomntools) {
    const char *p = strstr(vscomntools, "\\Common7\\Tools");
    path = p ? std::string(vscomntools, p) : vscomntools;
    return true;
  }
  return false;
}

void Windows::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                        ArgStringList &CC1Args) const {
  if (DriverArgs.hasArg(options::OPT_nostdinc))
    return;

  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
    SmallString<128> P(getDriver().ResourceDir);
    llvm::sys::path::append(P, "include");
    addSystemInclude(DriverArgs, CC1Args, P.str());
  }

  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
    return;

  // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
  if (const char *cl_include_dir = getenv("INCLUDE")) {
    SmallVector<StringRef, 8> Dirs;
    StringRef(cl_include_dir)
        .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
    for (StringRef Dir : Dirs)
      addSystemInclude(DriverArgs, CC1Args, Dir);
    if (!Dirs.empty())
      return;
  }

  std::string VSDir;
  std::string WindowsSDKDir;

  // When built with access to the proper Windows APIs, try to actually find
  // the correct include paths first.
  if (getVisualStudioDir(VSDir)) {
    SmallString<128> P;
    P = VSDir;
    llvm::sys::path::append(P, "VC\\include");
    addSystemInclude(DriverArgs, CC1Args, P.str());
    if (getWindowsSDKDir(WindowsSDKDir)) {
      P = WindowsSDKDir;
      llvm::sys::path::append(P, "include");
      addSystemInclude(DriverArgs, CC1Args, P.str());
    } else {
      P = VSDir;
      llvm::sys::path::append(P, "VC\\PlatformSDK\\Include");
      addSystemInclude(DriverArgs, CC1Args, P.str());
    }
    return;
  }

  // As a fallback, select default install paths.
  // FIXME: Don't guess drives and paths like this on Windows.
  const StringRef Paths[] = {
    "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
    "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
    "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
    "C:/Program Files/Microsoft Visual Studio 8/VC/include",
    "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
  };
  addSystemIncludes(DriverArgs, CC1Args, Paths);
}

void Windows::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
                                           ArgStringList &CC1Args) const {
  // FIXME: There should probably be logic here to find libc++ on Windows.
}
<commit_msg>Win64: Disable uwtable until we fix .pdata emission in LLVM<commit_after>//===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "ToolChains.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Path.h"

// Include the necessary headers to interface with the Windows registry and
// environment.
#if defined(LLVM_ON_WIN32)
#define USE_WIN32
#endif

#ifdef USE_WIN32
  #define WIN32_LEAN_AND_MEAN
  #define NOGDI
  #define NOMINMAX
  #include <windows.h>
#endif

using namespace clang::driver;
using namespace clang::driver::toolchains;
using namespace clang;
using namespace llvm::opt;

Windows::Windows(const Driver &D, const llvm::Triple& Triple,
                 const ArgList &Args)
  : ToolChain(D, Triple, Args) {
}

Tool *Windows::buildLinker() const {
  return new tools::visualstudio::Link(*this);
}

Tool *Windows::buildAssembler() const {
  if (getTriple().isOSBinFormatMachO())
    return new tools::darwin::Assemble(*this);
  getDriver().Diag(clang::diag::err_no_external_assembler);
  return nullptr;
}

bool Windows::IsIntegratedAssemblerDefault() const {
  return true;
}

bool Windows::IsUnwindTablesDefault() const {
  // FIXME: LLVM's lowering of Win64 data is broken right now.  MSVC's linker
  // says that our object files provide invalid .pdata contributions.  Until
  // that is fixed, don't ask for unwind tables.
  return false;
  //return getArch() == llvm::Triple::x86_64;
}

bool Windows::isPICDefault() const {
  return getArch() == llvm::Triple::x86_64;
}

bool Windows::isPIEDefault() const {
  return false;
}

bool Windows::isPICDefaultForced() const {
  return getArch() == llvm::Triple::x86_64;
}

/// \brief Read registry string.
/// This also supports a means to look for high-versioned keys by use
/// of a $VERSION placeholder in the key path.
/// $VERSION in the key path is a placeholder for the version number,
/// causing the highest value path to be searched for and used.
/// I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
/// There can be additional characters in the component.  Only the numberic
/// characters are compared.
static bool getSystemRegistryString(const char *keyPath, const char *valueName,
                                    char *value, size_t maxLength) {
#ifndef USE_WIN32
  return false;
#else
  HKEY hRootKey = NULL;
  HKEY hKey = NULL;
  const char* subKey = NULL;
  DWORD valueType;
  DWORD valueSize = maxLength - 1;
  long lResult;
  bool returnValue = false;

  if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
    hRootKey = HKEY_CLASSES_ROOT;
    subKey = keyPath + 18;
  } else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) {
    hRootKey = HKEY_USERS;
    subKey = keyPath + 11;
  } else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) {
    hRootKey = HKEY_LOCAL_MACHINE;
    subKey = keyPath + 19;
  } else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) {
    hRootKey = HKEY_CURRENT_USER;
    subKey = keyPath + 18;
  } else {
    return false;
  }

  const char *placeHolder = strstr(subKey, "$VERSION");
  char bestName[256];
  bestName[0] = '\0';
  // If we have a $VERSION placeholder, do the highest-version search.
  if (placeHolder) {
    const char *keyEnd = placeHolder - 1;
    const char *nextKey = placeHolder;
    // Find end of previous key.
    while ((keyEnd > subKey) && (*keyEnd != '\\'))
      keyEnd--;
    // Find end of key containing $VERSION.
    while (*nextKey && (*nextKey != '\\'))
      nextKey++;
    size_t partialKeyLength = keyEnd - subKey;
    char partialKey[256];
    if (partialKeyLength > sizeof(partialKey))
      partialKeyLength = sizeof(partialKey);
    strncpy(partialKey, subKey, partialKeyLength);
    partialKey[partialKeyLength] = '\0';
    HKEY hTopKey = NULL;
    lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
                           &hTopKey);
    if (lResult == ERROR_SUCCESS) {
      char keyName[256];
      int bestIndex = -1;
      double bestValue = 0.0;
      DWORD index, size = sizeof(keyName) - 1;
      for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
          NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
        const char *sp = keyName;
        while (*sp && !isDigit(*sp))
          sp++;
        if (!*sp)
          continue;
        const char *ep = sp + 1;
        while (*ep && (isDigit(*ep) || (*ep == '.')))
          ep++;
        char numBuf[32];
        strncpy(numBuf, sp, sizeof(numBuf) - 1);
        numBuf[sizeof(numBuf) - 1] = '\0';
        double dvalue = strtod(numBuf, NULL);
        if (dvalue > bestValue) {
          // Test that InstallDir is indeed there before keeping this index.
          // Open the chosen key path remainder.
          strcpy(bestName, keyName);
          // Append rest of key.
          strncat(bestName, nextKey, sizeof(bestName) - 1);
          bestName[sizeof(bestName) - 1] = '\0';
          lResult = RegOpenKeyEx(hTopKey, bestName, 0,
                                 KEY_READ | KEY_WOW64_32KEY, &hKey);
          if (lResult == ERROR_SUCCESS) {
            lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
              (LPBYTE)value, &valueSize);
            if (lResult == ERROR_SUCCESS) {
              bestIndex = (int)index;
              bestValue = dvalue;
              returnValue = true;
            }
            RegCloseKey(hKey);
          }
        }
        size = sizeof(keyName) - 1;
      }
      RegCloseKey(hTopKey);
    }
  } else {
    lResult = RegOpenKeyEx(hRootKey, subKey, 0, KEY_READ | KEY_WOW64_32KEY,
                           &hKey);
    if (lResult == ERROR_SUCCESS) {
      lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
        (LPBYTE)value, &valueSize);
      if (lResult == ERROR_SUCCESS)
        returnValue = true;
      RegCloseKey(hKey);
    }
  }
  return returnValue;
#endif // USE_WIN32
}

/// \brief Get Windows SDK installation directory.
static bool getWindowsSDKDir(std::string &path) {
  char windowsSDKInstallDir[256];
  // Try the Windows registry.
  bool hasSDKDir = getSystemRegistryString(
   "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
                                           "InstallationFolder",
                                           windowsSDKInstallDir,
                                           sizeof(windowsSDKInstallDir) - 1);
    // If we have both vc80 and vc90, pick version we were compiled with.
  if (hasSDKDir && windowsSDKInstallDir[0]) {
    path = windowsSDKInstallDir;
    return true;
  }
  return false;
}

// Get Visual Studio installation directory.
static bool getVisualStudioDir(std::string &path) {
  // First check the environment variables that vsvars32.bat sets.
  const char* vcinstalldir = getenv("VCINSTALLDIR");
  if (vcinstalldir) {
    char *p = const_cast<char *>(strstr(vcinstalldir, "\\VC"));
    if (p)
      *p = '\0';
    path = vcinstalldir;
    return true;
  }

  char vsIDEInstallDir[256];
  char vsExpressIDEInstallDir[256];
  // Then try the windows registry.
  bool hasVCDir = getSystemRegistryString(
    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
    "InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1);
  bool hasVCExpressDir = getSystemRegistryString(
    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
    "InstallDir", vsExpressIDEInstallDir, sizeof(vsExpressIDEInstallDir) - 1);
    // If we have both vc80 and vc90, pick version we were compiled with.
  if (hasVCDir && vsIDEInstallDir[0]) {
    char *p = (char*)strstr(vsIDEInstallDir, "\\Common7\\IDE");
    if (p)
      *p = '\0';
    path = vsIDEInstallDir;
    return true;
  }

  if (hasVCExpressDir && vsExpressIDEInstallDir[0]) {
    char *p = (char*)strstr(vsExpressIDEInstallDir, "\\Common7\\IDE");
    if (p)
      *p = '\0';
    path = vsExpressIDEInstallDir;
    return true;
  }

  // Try the environment.
  const char *vs100comntools = getenv("VS100COMNTOOLS");
  const char *vs90comntools = getenv("VS90COMNTOOLS");
  const char *vs80comntools = getenv("VS80COMNTOOLS");

  const char *vscomntools = nullptr;

  // Find any version we can
  if (vs100comntools)
    vscomntools = vs100comntools;
  else if (vs90comntools)
    vscomntools = vs90comntools;
  else if (vs80comntools)
    vscomntools = vs80comntools;

  if (vscomntools && *vscomntools) {
    const char *p = strstr(vscomntools, "\\Common7\\Tools");
    path = p ? std::string(vscomntools, p) : vscomntools;
    return true;
  }
  return false;
}

void Windows::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                        ArgStringList &CC1Args) const {
  if (DriverArgs.hasArg(options::OPT_nostdinc))
    return;

  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
    SmallString<128> P(getDriver().ResourceDir);
    llvm::sys::path::append(P, "include");
    addSystemInclude(DriverArgs, CC1Args, P.str());
  }

  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
    return;

  // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
  if (const char *cl_include_dir = getenv("INCLUDE")) {
    SmallVector<StringRef, 8> Dirs;
    StringRef(cl_include_dir)
        .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
    for (StringRef Dir : Dirs)
      addSystemInclude(DriverArgs, CC1Args, Dir);
    if (!Dirs.empty())
      return;
  }

  std::string VSDir;
  std::string WindowsSDKDir;

  // When built with access to the proper Windows APIs, try to actually find
  // the correct include paths first.
  if (getVisualStudioDir(VSDir)) {
    SmallString<128> P;
    P = VSDir;
    llvm::sys::path::append(P, "VC\\include");
    addSystemInclude(DriverArgs, CC1Args, P.str());
    if (getWindowsSDKDir(WindowsSDKDir)) {
      P = WindowsSDKDir;
      llvm::sys::path::append(P, "include");
      addSystemInclude(DriverArgs, CC1Args, P.str());
    } else {
      P = VSDir;
      llvm::sys::path::append(P, "VC\\PlatformSDK\\Include");
      addSystemInclude(DriverArgs, CC1Args, P.str());
    }
    return;
  }

  // As a fallback, select default install paths.
  // FIXME: Don't guess drives and paths like this on Windows.
  const StringRef Paths[] = {
    "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
    "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
    "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
    "C:/Program Files/Microsoft Visual Studio 8/VC/include",
    "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
  };
  addSystemIncludes(DriverArgs, CC1Args, Paths);
}

void Windows::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
                                           ArgStringList &CC1Args) const {
  // FIXME: There should probably be logic here to find libc++ on Windows.
}
<|endoftext|>


<commit_before>#include "log.h"

#include <ctime>
#include <cstring>
#include <algorithm>

namespace oak::log {

	Logger cout{ "msg" };
	Logger cwarn{ "warn" };
	Logger cerr{ "err" };

	Logger::Logger(const char* name) : name_{ name } {

	}

	void Logger::addStream(Stream *stream) {
		streams_.push_back(stream);
	}

	void Logger::removeStream(Stream *stream) {
		streams_.erase(std::remove(std::begin(streams_), std::end(streams_), stream), std::end(streams_));
	}

	void Logger::print(const char* text, Level level, const char* file, int line) {
		memset(buffer_, 0, 2048);
		//get time info
		time_t t = time(NULL);
		struct tm *tm = localtime(&t);
		switch (level) {
		case Level::MINIMAL:
			sprintf(buffer_, "[%s]: %s\n", name_, text);
		break;
		case Level::NORMAL:
			sprintf(buffer_, "[%i:%i:%i %i/%i/%i][%s]: %s\n",
				tm->tm_hour, tm->tm_min, tm->tm_sec,
				tm->tm_mon+1, tm->tm_mday, 1900+tm->tm_year,
				name_, text);
		break;
		case Level::VERBOSE:
			sprintf(buffer_, "[%i:%i:%i %i/%i/%i][file]:%s:%i[%s]: %s\n",
				tm->tm_hour, tm->tm_min, tm->tm_sec,
				tm->tm_mon+1, tm->tm_mday, 1900+tm->tm_year,
				file, line, name_, text);
		break;
		}
		flush();
	}

	void Logger::flush() {
		for (auto& stream : streams_) {
			stream->write(buffer_);
		}
	}

}<commit_msg>fixed log<commit_after>#include "log.h"

#include <ctime>
#include <cstring>
#include <algorithm>

namespace oak::log {

	Logger cout{ "msg" };
	Logger cwarn{ "warn" };
	Logger cerr{ "err" };

	Logger::Logger(const char* name) : name_{ name } {

	}

	void Logger::addStream(Stream *stream) {
		streams_.push_back(stream);
	}

	void Logger::removeStream(Stream *stream) {
		streams_.erase(std::remove(std::begin(streams_), std::end(streams_), stream), std::end(streams_));
	}

	void Logger::print(const char* text, Level level, const char* file, int line) {
		memset(buffer_, 0, 2048);
		//get time info
		time_t t = time(NULL);
		struct tm *tm = localtime(&t);
		switch (level) {
		case Level::MINIMAL:
			sprintf(buffer_, "[%s]: %s\n", name_, text);
		break;
		case Level::NORMAL:
			sprintf(buffer_, "[%i:%i:%i %i/%i/%i][%s]: %s\n",
				tm->tm_hour, tm->tm_min, tm->tm_sec,
				tm->tm_mon+1, tm->tm_mday, 1900+tm->tm_year,
				name_, text);
		break;
		case Level::VERBOSE:
			sprintf(buffer_, "[%i:%i:%i %i/%i/%i][file]:%s:%i[%s]: %s\n",
				tm->tm_hour, tm->tm_min, tm->tm_sec,
				tm->tm_mon+1, tm->tm_mday, 1900+tm->tm_year,
				file, line, name_, text);
		break;
		}
		flush();
	}

	void Logger::flush() {

		for (auto& stream : streams_) {
			stream->buffer->write(strlen(buffer_), buffer_);
		}
	}

}<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This is a file for random testcases that we run into that at one point or
// another have crashed the program.

#include "chrome/test/ui/ui_test.h"

#include "base/basictypes.h"
#include "base/file_path.h"
#include "chrome/common/chrome_switches.h"
#include "net/base/net_util.h"

class GoogleTest : public UITest {
 protected:
  GoogleTest() : UITest() {
    FilePath test_file =
        test_data_directory_.AppendASCII("google").AppendASCII("google.html");
    set_homepage(GURL(net::FilePathToFileURL(test_file)).spec());
  }
};

// Flakily fails under Valgrind, see http://crbug.com/85863.
#if defined(OS_MACOSX)
#define MAYBE_Crash FLAKY_Crash
#elese
#define MAYBE_Crash Crash
#endif  // defined(OS_MACOSX)
TEST_F(GoogleTest, MAYBE_Crash) {
  std::wstring page_title = L"Google";

  // Make sure the navigation succeeded.
  EXPECT_EQ(page_title, GetActiveTabTitle());

  // UITest will check if this crashed.
}

class ColumnLayout : public UITest {
 protected:
  ColumnLayout() : UITest() {
    FilePath test_file = test_data_directory_.AppendASCII("columns.html");
    set_homepage(GURL(net::FilePathToFileURL(test_file)).spec());
  }
};

TEST_F(ColumnLayout, Crash) {
  std::wstring page_title = L"Column test";

  // Make sure the navigation succeeded.
  EXPECT_EQ(page_title, GetActiveTabTitle());

  // UITest will check if this crashed.
}

// By passing kTryChromeAgain with a magic value > 10000 we cause Chrome
// to exit fairly early.
// Quickly exiting Chrome (regardless of this particular flag -- it
// doesn't do anything other than cause Chrome to quit on startup on
// non-Windows) was a cause of crashes (see bug 34799 for example) so
// this is a useful test of the startup/quick-shutdown cycle.
class EarlyReturnTest : public UITest {
 public:
  EarlyReturnTest() {
    wait_for_initial_loads_ = false;  // Don't wait for any pages to load.
    launch_arguments_.AppendSwitchASCII(switches::kTryChromeAgain, "10001");
  }
};

// Disabled: http://crbug.com/45115
// Due to limitations in our test infrastructure, this test currently doesn't
// work.
TEST_F(EarlyReturnTest, DISABLED_ToastCrasher) {
  // UITest will check if this crashed.
}
<commit_msg>Revert 88791 - Valgrind: Mark GoogleTest.Crash as flaky under Mac.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This is a file for random testcases that we run into that at one point or
// another have crashed the program.

#include "chrome/test/ui/ui_test.h"

#include "base/basictypes.h"
#include "base/file_path.h"
#include "chrome/common/chrome_switches.h"
#include "net/base/net_util.h"

class GoogleTest : public UITest {
 protected:
  GoogleTest() : UITest() {
    FilePath test_file =
        test_data_directory_.AppendASCII("google").AppendASCII("google.html");
    set_homepage(GURL(net::FilePathToFileURL(test_file)).spec());
  }
};

TEST_F(GoogleTest, Crash) {
  std::wstring page_title = L"Google";

  // Make sure the navigation succeeded.
  EXPECT_EQ(page_title, GetActiveTabTitle());

  // UITest will check if this crashed.
}

class ColumnLayout : public UITest {
 protected:
  ColumnLayout() : UITest() {
    FilePath test_file = test_data_directory_.AppendASCII("columns.html");
    set_homepage(GURL(net::FilePathToFileURL(test_file)).spec());
  }
};

TEST_F(ColumnLayout, Crash) {
  std::wstring page_title = L"Column test";

  // Make sure the navigation succeeded.
  EXPECT_EQ(page_title, GetActiveTabTitle());

  // UITest will check if this crashed.
}

// By passing kTryChromeAgain with a magic value > 10000 we cause Chrome
// to exit fairly early.
// Quickly exiting Chrome (regardless of this particular flag -- it
// doesn't do anything other than cause Chrome to quit on startup on
// non-Windows) was a cause of crashes (see bug 34799 for example) so
// this is a useful test of the startup/quick-shutdown cycle.
class EarlyReturnTest : public UITest {
 public:
  EarlyReturnTest() {
    wait_for_initial_loads_ = false;  // Don't wait for any pages to load.
    launch_arguments_.AppendSwitchASCII(switches::kTryChromeAgain, "10001");
  }
};

// Disabled: http://crbug.com/45115
// Due to limitations in our test infrastructure, this test currently doesn't
// work.
TEST_F(EarlyReturnTest, DISABLED_ToastCrasher) {
  // UITest will check if this crashed.
}
<|endoftext|>