<commit_before>/***********************************************************************
    created:    20th February 2010
    author:     Lukas E Meindl

    purpose:    Implementation of the class used to provide conversions
                between the ColourPicker colour types
*************************************************************************/
/***************************************************************************
*   Copyright (C) 2004 - 2010 Paul D Turner & The CEGUI Development Team
*
*   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 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.
***************************************************************************/
#include "CEGUI/CommonDialogs/ColourPicker/Conversions.h"
#include <math.h>
#include <algorithm>

namespace CEGUI
{

//----------------------------------------------------------------------------//
const float ColourPickerConversions::Xn(0.95047f);
const float ColourPickerConversions::Yn(1.00000f);
const float ColourPickerConversions::Zn(1.08883f);

const float ColourPickerConversions::LAB_COMPARE_VALUE_CONST(0.00885645167903563081717167575546f);

//----------------------------------------------------------------------------//
void ColourPickerConversions::clamp(float& value, float min_val, float max_val)
{
    value = value < min_val ? min_val : (value > max_val ? max_val : value);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toX(unsigned char R, unsigned char G, unsigned char B)
{
    return toX(R / 255.0f, G / 255.0f, B / 255.0f);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toY(unsigned char R, unsigned char G, unsigned char B)
{
    return toY(R / 255.0f, G / 255.0f, B / 255.0f);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toZ(unsigned char R, unsigned char G, unsigned char B)
{
    return toZ(R / 255.0f, G / 255.0f, B / 255.0f);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toX(float R, float G, float B)
{
    return (0.4124564f * R + 0.3575761f * G + 0.1804375f * B);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toY(float R, float G, float B)
{
    return (0.2126729f * R + 0.7151522f * G + 0.0721750f * B);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toZ(float R, float G, float B)
{
    return (0.0193339f * R + 0.1191920f * G + 0.9503041f * B);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toL(float Y)
{
    return (116.0f * YNormCalc(Y) - 16.0f);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toA(float X, float Y)
{
    return (500.0f * (XNormCalc(X) - YNormCalc(Y)));
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toB(float Y, float Z)
{
    return (200.0f * (YNormCalc(Y) - ZNormCalc(Z)));
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::XNormCalc(float X)
{
    float div = (X / Xn);
    return normCalc(div);

}

//----------------------------------------------------------------------------//
float ColourPickerConversions::YNormCalc(float Y)
{
    float div = (Y / Yn);
    return normCalc(div);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::ZNormCalc(float Z)
{
    float div = (Z / Zn);
    return normCalc(div);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::normCalc(float div)
{
    if (div < LAB_COMPARE_VALUE_CONST)
        return ((24389.0f / 27.0f * div + 16.0f) / 116.0f);
    else
        return pow(div, 1.0f / 3.0f);
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::toRGB(const Lab_Colour& colour)
{
    return toRGB(colour.L, colour.a, colour.b);
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::toRGB(float L, float a, float b)
{
    float vy = (L + 16.0f) / 116.0f;
    float vx = a / 500.0f + vy;
    float vz = vy - b / 200.0f;

    {
        float vx3 = pow(vx, 3);
        float vy3 = pow(vy, 3);
        float vz3 = pow(vz, 3);

        if (vy3 > LAB_COMPARE_VALUE_CONST)
            vy = vy3;
        else
            vy = (vy - 16.0f / 116.0f) / 7.787f;

        if (vx3 > LAB_COMPARE_VALUE_CONST)
            vx = vx3;
        else
            vx = (vx - 16.0f / 116.0f) / 7.787f;

        if (vz3 > LAB_COMPARE_VALUE_CONST)
            vz = vz3;
        else
            vz = (vz - 16.0f / 116.0f) / 7.787f;
    }

    vx *= Xn;
    vz *= Zn;

    float vr = vx *  3.2406f + vy * -1.5372f + vz * -0.4986f;
    float vg = vx * -0.9689f + vy *  1.8758f + vz *  0.0415f;
    float vb = vx *  0.0557f + vy * -0.2040f + vz *  1.0570f;

    clamp(vr, 0.0f, 1.0f);
    clamp(vg, 0.0f, 1.0f);
    clamp(vb, 0.0f, 1.0f);

    return RGB_Colour(static_cast<unsigned char>(255.0f * vr),
                      static_cast<unsigned char>(255.0f * vg),
                      static_cast<unsigned char>(255.0f * vb));
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::toRGB(const CEGUI::Colour& colour)
{
    return RGB_Colour(static_cast<unsigned char>(colour.getRed() * 255.0f),
                      static_cast<unsigned char>(colour.getGreen() * 255.0f),
                      static_cast<unsigned char>(colour.getBlue() * 255.0f));
}

//----------------------------------------------------------------------------//
CEGUI::Colour ColourPickerConversions::toCeguiColour(const RGB_Colour& colourRGB)
{
    return CEGUI::Colour(colourRGB.r / 255.0f,
                         colourRGB.g / 255.0f,
                         colourRGB.b / 255.0f);
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::linearInterpolationRGB(float interPolBalance,
        const RGB_Colour& start,
        const RGB_Colour& end)
{
    RGB_Colour colour;

    clampInterpolationValue(interPolBalance);

    colour.r = static_cast<unsigned char>(
                   (1 - interPolBalance) * start.r + (interPolBalance * end.r));
    colour.g = static_cast<unsigned char>(
                   (1 - interPolBalance) * start.g + (interPolBalance * end.g));
    colour.b = static_cast<unsigned char>(
                   (1 - interPolBalance) * start.b + (interPolBalance * end.b));

    return colour;
}

//----------------------------------------------------------------------------//
Lab_Colour ColourPickerConversions::linearInterpolationLab(float interPolBalance,
        const Lab_Colour& start,
        const Lab_Colour& end)
{
    Lab_Colour colour;

    clampInterpolationValue(interPolBalance);

    colour.L = (1 - interPolBalance) * start.L + (interPolBalance * end.L);
    colour.a = (1 - interPolBalance) * start.a + (interPolBalance * end.a);
    colour.b = (1 - interPolBalance) * start.b + (interPolBalance * end.b);

    return colour;
}

//----------------------------------------------------------------------------//
HSV_Colour ColourPickerConversions::linearInterpolationHSV(float interPolBalance,
        const HSV_Colour& start,
        const HSV_Colour& end)
{
    HSV_Colour colour;

    clampInterpolationValue(interPolBalance);

    colour.H = (1 - interPolBalance) * start.H + (interPolBalance * end.H);
    colour.S = (1 - interPolBalance) * start.S + (interPolBalance * end.S);
    colour.V = (1 - interPolBalance) * start.V + (interPolBalance * end.V);

    return colour;
}

//----------------------------------------------------------------------------//
unsigned char ColourPickerConversions::linearInterpolationAlpha(float interPolBalance,
        unsigned char startAlpha,
        unsigned char endAlpha)
{
    clampInterpolationValue(interPolBalance);

    return static_cast<unsigned char>(
               (1 - interPolBalance) * startAlpha + (interPolBalance * endAlpha));
}

//----------------------------------------------------------------------------//
void ColourPickerConversions::clampInterpolationValue(float& interPolBalance)
{
    interPolBalance = std::max(0.0f, interPolBalance);
    interPolBalance = std::min(1.0f, interPolBalance);
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::toRGB(const HSV_Colour& colour)
{
    float r = 0.0f;
    float g = 0.0f;
    float b = 0.0f;

    int i = (int)(colour.H * 6.0f);
    float f = colour.H * 6 - i;
    float p = colour.V * (1 - colour.S);
    float q = colour.V * (1 - f * colour.S);
    float t = colour.V * (1 - (1 - f) * colour.S);

    switch (i % 6)
    {
    case 0:
        r = colour.V;
        g = t;
        b = p;
        break;

    case 1:
        r = q;
        g = colour.V;
        b = p;
        break;

    case 2:
        r = p;
        g = colour.V;
        b = t;
        break;

    case 3:
        r = p;
        g = q;
        b = colour.V;
        break;

    case 4:
        r = t;
        g = p;
        b = colour.V;
        break;

    case 5:
        r = colour.V;
        g = p;
        b = q;
        break;
    }

    return RGB_Colour(static_cast<unsigned char>(r * 255),
                      static_cast<unsigned char>(g * 255),
                      static_cast<unsigned char>(b * 255));
}
//----------------------------------------------------------------------------//

Lab_Colour ColourPickerConversions::toLab(RGB_Colour colour)
{
    float X = toX(colour.r, colour.g, colour.b);
    float Y = toY(colour.r, colour.g, colour.b);
    float Z = toZ(colour.r, colour.g, colour.b);

    float L = toL(Y);
    float a = toA(X, Y);
    float b = toB(Y, Z);

    return Lab_Colour(L, a, b);
}

//----------------------------------------------------------------------------//
HSV_Colour ColourPickerConversions::toHSV(RGB_Colour colour)
{
    float r = colour.r / 255.0f;
    float g = colour.g / 255.0f;
    float b = colour.b / 255.0f;

    bool maxCompRed = false;
    bool maxCompGreen = false;
    float max_comp = b;

    if(r > g && r > b)
    {
        maxCompRed = true;
        max_comp = r;
    }
    else if(g > b)
    {
        maxCompGreen = true;
        max_comp = g;
    }

    float min_comp = ceguimin(ceguimin(r, g), b);
    float h;
    float s;
    float v = max_comp;

    float diff = max_comp - min_comp;
    s = (max_comp == 0.0f ? 0.0f : diff / max_comp);

    if (max_comp == min_comp)
    {
        h = 0; // achromatic
    }
    else
    {
        if (maxCompRed)
            h = (g - b) / diff + (g < b ? 6.0f : 0.0f);

        if (maxCompGreen)
            h = (b - r) / diff + 2.0f;

        else
            h = (r - g) / diff + 4.0f;

        h /= 6.0f;
    }

    return HSV_Colour(h, s, v);
}

//----------------------------------------------------------------------------//

}

<commit_msg>MOD: Fixed a small HSV conversion bug<commit_after>/***********************************************************************
    created:    20th February 2010
    author:     Lukas E Meindl

    purpose:    Implementation of the class used to provide conversions
                between the ColourPicker colour types
*************************************************************************/
/***************************************************************************
*   Copyright (C) 2004 - 2010 Paul D Turner & The CEGUI Development Team
*
*   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 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.
***************************************************************************/
#include "CEGUI/CommonDialogs/ColourPicker/Conversions.h"
#include <math.h>
#include <algorithm>

namespace CEGUI
{

//----------------------------------------------------------------------------//
const float ColourPickerConversions::Xn(0.95047f);
const float ColourPickerConversions::Yn(1.00000f);
const float ColourPickerConversions::Zn(1.08883f);

const float ColourPickerConversions::LAB_COMPARE_VALUE_CONST(0.00885645167903563081717167575546f);

//----------------------------------------------------------------------------//
void ColourPickerConversions::clamp(float& value, float min_val, float max_val)
{
    value = value < min_val ? min_val : (value > max_val ? max_val : value);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toX(unsigned char R, unsigned char G, unsigned char B)
{
    return toX(R / 255.0f, G / 255.0f, B / 255.0f);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toY(unsigned char R, unsigned char G, unsigned char B)
{
    return toY(R / 255.0f, G / 255.0f, B / 255.0f);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toZ(unsigned char R, unsigned char G, unsigned char B)
{
    return toZ(R / 255.0f, G / 255.0f, B / 255.0f);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toX(float R, float G, float B)
{
    return (0.4124564f * R + 0.3575761f * G + 0.1804375f * B);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toY(float R, float G, float B)
{
    return (0.2126729f * R + 0.7151522f * G + 0.0721750f * B);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toZ(float R, float G, float B)
{
    return (0.0193339f * R + 0.1191920f * G + 0.9503041f * B);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toL(float Y)
{
    return (116.0f * YNormCalc(Y) - 16.0f);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toA(float X, float Y)
{
    return (500.0f * (XNormCalc(X) - YNormCalc(Y)));
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::toB(float Y, float Z)
{
    return (200.0f * (YNormCalc(Y) - ZNormCalc(Z)));
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::XNormCalc(float X)
{
    float div = (X / Xn);
    return normCalc(div);

}

//----------------------------------------------------------------------------//
float ColourPickerConversions::YNormCalc(float Y)
{
    float div = (Y / Yn);
    return normCalc(div);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::ZNormCalc(float Z)
{
    float div = (Z / Zn);
    return normCalc(div);
}

//----------------------------------------------------------------------------//
float ColourPickerConversions::normCalc(float div)
{
    if (div < LAB_COMPARE_VALUE_CONST)
        return ((24389.0f / 27.0f * div + 16.0f) / 116.0f);
    else
        return pow(div, 1.0f / 3.0f);
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::toRGB(const Lab_Colour& colour)
{
    return toRGB(colour.L, colour.a, colour.b);
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::toRGB(float L, float a, float b)
{
    float vy = (L + 16.0f) / 116.0f;
    float vx = a / 500.0f + vy;
    float vz = vy - b / 200.0f;

    {
        float vx3 = pow(vx, 3);
        float vy3 = pow(vy, 3);
        float vz3 = pow(vz, 3);

        if (vy3 > LAB_COMPARE_VALUE_CONST)
            vy = vy3;
        else
            vy = (vy - 16.0f / 116.0f) / 7.787f;

        if (vx3 > LAB_COMPARE_VALUE_CONST)
            vx = vx3;
        else
            vx = (vx - 16.0f / 116.0f) / 7.787f;

        if (vz3 > LAB_COMPARE_VALUE_CONST)
            vz = vz3;
        else
            vz = (vz - 16.0f / 116.0f) / 7.787f;
    }

    vx *= Xn;
    vz *= Zn;

    float vr = vx *  3.2406f + vy * -1.5372f + vz * -0.4986f;
    float vg = vx * -0.9689f + vy *  1.8758f + vz *  0.0415f;
    float vb = vx *  0.0557f + vy * -0.2040f + vz *  1.0570f;

    clamp(vr, 0.0f, 1.0f);
    clamp(vg, 0.0f, 1.0f);
    clamp(vb, 0.0f, 1.0f);

    return RGB_Colour(static_cast<unsigned char>(255.0f * vr),
                      static_cast<unsigned char>(255.0f * vg),
                      static_cast<unsigned char>(255.0f * vb));
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::toRGB(const CEGUI::Colour& colour)
{
    return RGB_Colour(static_cast<unsigned char>(colour.getRed() * 255.0f),
                      static_cast<unsigned char>(colour.getGreen() * 255.0f),
                      static_cast<unsigned char>(colour.getBlue() * 255.0f));
}

//----------------------------------------------------------------------------//
CEGUI::Colour ColourPickerConversions::toCeguiColour(const RGB_Colour& colourRGB)
{
    return CEGUI::Colour(colourRGB.r / 255.0f,
                         colourRGB.g / 255.0f,
                         colourRGB.b / 255.0f);
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::linearInterpolationRGB(float interPolBalance,
        const RGB_Colour& start,
        const RGB_Colour& end)
{
    RGB_Colour colour;

    clampInterpolationValue(interPolBalance);

    colour.r = static_cast<unsigned char>(
                   (1 - interPolBalance) * start.r + (interPolBalance * end.r));
    colour.g = static_cast<unsigned char>(
                   (1 - interPolBalance) * start.g + (interPolBalance * end.g));
    colour.b = static_cast<unsigned char>(
                   (1 - interPolBalance) * start.b + (interPolBalance * end.b));

    return colour;
}

//----------------------------------------------------------------------------//
Lab_Colour ColourPickerConversions::linearInterpolationLab(float interPolBalance,
        const Lab_Colour& start,
        const Lab_Colour& end)
{
    Lab_Colour colour;

    clampInterpolationValue(interPolBalance);

    colour.L = (1 - interPolBalance) * start.L + (interPolBalance * end.L);
    colour.a = (1 - interPolBalance) * start.a + (interPolBalance * end.a);
    colour.b = (1 - interPolBalance) * start.b + (interPolBalance * end.b);

    return colour;
}

//----------------------------------------------------------------------------//
HSV_Colour ColourPickerConversions::linearInterpolationHSV(float interPolBalance,
        const HSV_Colour& start,
        const HSV_Colour& end)
{
    HSV_Colour colour;

    clampInterpolationValue(interPolBalance);

    colour.H = (1 - interPolBalance) * start.H + (interPolBalance * end.H);
    colour.S = (1 - interPolBalance) * start.S + (interPolBalance * end.S);
    colour.V = (1 - interPolBalance) * start.V + (interPolBalance * end.V);

    return colour;
}

//----------------------------------------------------------------------------//
unsigned char ColourPickerConversions::linearInterpolationAlpha(float interPolBalance,
        unsigned char startAlpha,
        unsigned char endAlpha)
{
    clampInterpolationValue(interPolBalance);

    return static_cast<unsigned char>(
               (1 - interPolBalance) * startAlpha + (interPolBalance * endAlpha));
}

//----------------------------------------------------------------------------//
void ColourPickerConversions::clampInterpolationValue(float& interPolBalance)
{
    interPolBalance = std::max(0.0f, interPolBalance);
    interPolBalance = std::min(1.0f, interPolBalance);
}

//----------------------------------------------------------------------------//
RGB_Colour ColourPickerConversions::toRGB(const HSV_Colour& colour)
{
    float r = 0.0f;
    float g = 0.0f;
    float b = 0.0f;

    int i = (int)(colour.H * 6.0f);
    float f = colour.H * 6 - i;
    float p = colour.V * (1 - colour.S);
    float q = colour.V * (1 - f * colour.S);
    float t = colour.V * (1 - (1 - f) * colour.S);

    switch (i % 6)
    {
    case 0:
        r = colour.V;
        g = t;
        b = p;
        break;

    case 1:
        r = q;
        g = colour.V;
        b = p;
        break;

    case 2:
        r = p;
        g = colour.V;
        b = t;
        break;

    case 3:
        r = p;
        g = q;
        b = colour.V;
        break;

    case 4:
        r = t;
        g = p;
        b = colour.V;
        break;

    case 5:
        r = colour.V;
        g = p;
        b = q;
        break;
    }

    return RGB_Colour(static_cast<unsigned char>(r * 255),
                      static_cast<unsigned char>(g * 255),
                      static_cast<unsigned char>(b * 255));
}
//----------------------------------------------------------------------------//

Lab_Colour ColourPickerConversions::toLab(RGB_Colour colour)
{
    float X = toX(colour.r, colour.g, colour.b);
    float Y = toY(colour.r, colour.g, colour.b);
    float Z = toZ(colour.r, colour.g, colour.b);

    float L = toL(Y);
    float a = toA(X, Y);
    float b = toB(Y, Z);

    return Lab_Colour(L, a, b);
}

//----------------------------------------------------------------------------//
HSV_Colour ColourPickerConversions::toHSV(RGB_Colour colour)
{
    float r = colour.r / 255.0f;
    float g = colour.g / 255.0f;
    float b = colour.b / 255.0f;

    bool maxCompRed = false;
    bool maxCompGreen = false;
    float max_comp = b;

    if(r > g && r > b)
    {
        maxCompRed = true;
        max_comp = r;
    }
    else if(g > b)
    {
        maxCompGreen = true;
        max_comp = g;
    }

    float min_comp = ceguimin(ceguimin(r, g), b);
    float h;
    float s;
    float v = max_comp;

    float diff = max_comp - min_comp;
    s = (max_comp == 0.0f ? 0.0f : diff / max_comp);

    if (max_comp == min_comp)
    {
        h = 0; // achromatic
    }
    else
    {
        if (maxCompRed)
        {
            h = (g - b) / diff + (g < b ? 6.0f : 0.0f);
        }
        else if (maxCompGreen)
        {
            h = (b - r) / diff + 2.0f;
        }
        else
        {
            h = (r - g) / diff + 4.0f;
        }

        h /= 6.0f;
    }

    return HSV_Colour(h, s, v);
}

//----------------------------------------------------------------------------//

}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "otbWrapperApplicationRegistry.h"

int main(int argc,char* argv[])
{
  using otb::Wrapper::ApplicationRegistry;
  using otb::Wrapper::Application;

  if (argc != 5)
    {
    std::cout << "Usage: 0000478-UncaughtException app_module_path stereo_ref stereo_sec output_file" << std::endl;
    return 1;
    }

  ApplicationRegistry::SetApplicationPath(argv[1]);
  Application::Pointer myApp = ApplicationRegistry::CreateApplication("StereoSensorModelToElevationMap");

  if (myApp.IsNull())
    {
    std::cout << "Application not created" << std::endl;
    return 1;
    }

  myApp->Init();

  myApp->SetParameterString("ref", argv[2]);
  myApp->SetParameterString("sec", argv[3]);
  myApp->SetParameterString("out", argv[4]);
  myApp->SetParameterString("elev","dem");
  myApp->SetParameterString("elev.dem.path", "FAKE_DEM_PATH");
  myApp->SetParameterString("elev.dem.geoid", "FAKE_GEOID_PATH");

  std::cout << "Try-catch section" << std::endl;
  try
    {
    myApp->ExecuteAndWriteOutput();
    }
  catch(...)
    {
    std::cerr << "An unknown exception has been caught !" << std::endl;
    }

  return 0;
}
<commit_msg>TEST: Fixing test code following elevation management refactoring<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "otbWrapperApplicationRegistry.h"

int main(int argc,char* argv[])
{
  using otb::Wrapper::ApplicationRegistry;
  using otb::Wrapper::Application;

  if (argc != 5)
    {
    std::cout << "Usage: 0000478-UncaughtException app_module_path stereo_ref stereo_sec output_file" << std::endl;
    return 1;
    }

  ApplicationRegistry::SetApplicationPath(argv[1]);
  Application::Pointer myApp = ApplicationRegistry::CreateApplication("StereoSensorModelToElevationMap");

  if (myApp.IsNull())
    {
    std::cout << "Application not created" << std::endl;
    return 1;
    }

  myApp->Init();

  myApp->SetParameterString("ref", argv[2]);
  myApp->SetParameterString("sec", argv[3]);
  myApp->SetParameterString("out", argv[4]);
  myApp->SetParameterString("elev.dem", "FAKE_DEM_PATH");
  myApp->SetParameterString("elev.geoid", "FAKE_GEOID_PATH");

  std::cout << "Try-catch section" << std::endl;
  try
    {
    myApp->ExecuteAndWriteOutput();
    }
  catch(...)
    {
    std::cerr << "An unknown exception has been caught !" << std::endl;
    }

  return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: urp_marshal.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 22:47:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include <string.h>
#include <osl/diagnose.h>
#include <rtl/alloc.h>

#include <uno/any2.h>
#include <uno/sequence2.h>

#include "urp_marshal.hxx"

using namespace ::rtl;

using namespace ::com::sun::star::uno;

namespace bridges_urp {

static int g_nDetectLittleEndian = 1;
char g_bMarshalSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0];

Marshal::Marshal( urp_BridgeImpl *pBridgeImpl,
                  sal_Int32 nBufferSize,
                  urp_extractOidCallback callback) :
    m_nBufferSize( nBufferSize ),
    m_base( (sal_Int8*)rtl_allocateMemory( nBufferSize ) ),
    m_pos( m_base + 2*sizeof( sal_Int32 ) ),
    m_pBridgeImpl( pBridgeImpl ),
    m_callback( callback )
{}

Marshal::~Marshal( )
{
    rtl_freeMemory( m_base );
}

void Marshal::packOid( const ::rtl::OUString & oid )
{
    sal_uInt16 nIndex;
    if( oid.getLength() )
    {
        nIndex = m_pBridgeImpl->m_oidCacheOut.seek( oid );
        if( 0xffff == nIndex )
        {
            nIndex = m_pBridgeImpl->m_oidCacheOut.put( oid );
            packString( (void*)(&oid.pData) );
        }
        else
        {
            OUString dummy;
            packString( &dummy );
        }
    }
    else
    {
        // null reference
        nIndex = 0xffff;
        OUString dummy;
        packString( &dummy );
    }
    packInt16( &nIndex );
}

void Marshal::packTid( const ByteSequence & threadId, sal_Bool bIgnoreCache )
{

    sal_uInt16 nIndex = 0xffff;
    if( ! bIgnoreCache )
    {
        nIndex = m_pBridgeImpl->m_tidCacheOut.seek( threadId );
    }

    if( 0xffff == nIndex )
    {
        if( ! bIgnoreCache )
        {
            nIndex = m_pBridgeImpl->m_tidCacheOut.put( threadId );
        }
        packByteSequence( (sal_Int8*) threadId.getConstArray() ,threadId.getLength());
    }
    else
    {
        packByteSequence( 0 , 0 );
    }
    packInt16( &nIndex );
}

void Marshal::packType( void *pSource )
{
    typelib_TypeDescriptionReference *pRef =
        *(typelib_TypeDescriptionReference ** ) pSource;

    OSL_ASSERT( pRef );

    sal_uInt8 nTypeClass = ( sal_uInt8 ) pRef->eTypeClass;

    if( nTypeClass <= /* any*/ 14 )
    {
        packInt8( (sal_Int8*)&nTypeClass );
    }
    else
    {
        OUString sTypeName;
        sal_uInt16 nIndex = 0xffff;

        nIndex = m_pBridgeImpl->m_typeCacheOut.seek( *(Type*)&pRef );
        if( 0xffff == nIndex )
        {
            // put it into the cache
            nIndex = m_pBridgeImpl->m_typeCacheOut.put( *(Type*)&pRef );
            sTypeName = pRef->pTypeName;
            nTypeClass = nTypeClass | 0x80;
        }
        packInt8( &nTypeClass  );
        packInt16( &nIndex );
        if( 0x80 & nTypeClass )
        {
            packString( &sTypeName );
        }
    }
}

sal_Bool Marshal::packRecursive( void *pSource , typelib_TypeDescription *pType )
{
    sal_Bool bSuccess = sal_True;
    switch( pType->eTypeClass )
    {
    case typelib_TypeClass_EXCEPTION:
    case typelib_TypeClass_STRUCT:
    {
        typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription*)pType;

        if (pCompType->pBaseTypeDescription)
        {
            bSuccess = pack( pSource , (typelib_TypeDescription*) pCompType->pBaseTypeDescription );
        }

        // then construct members
        typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
        sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
        sal_Int32 nDescr = pCompType->nMembers;

        for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
        {
              typelib_TypeDescription * pMemberType = 0;
              TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] );
            if( pMemberType )
            {
                bSuccess = bSuccess && pack( (char*)pSource + pMemberOffsets[nPos] , pMemberType );
                TYPELIB_DANGER_RELEASE( pMemberType );
            }
            else
            {
                OUStringBuffer buf( 64 );
                buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
                buf.append( ppTypeRefs[nPos]->pTypeName );
                m_pBridgeImpl->addError( buf.makeStringAndClear() );
                bSuccess = sal_False;
            }
        }
        break;
    }
    case typelib_TypeClass_SEQUENCE:
    {
        typelib_IndirectTypeDescription *pIndirectType =
            ( typelib_IndirectTypeDescription* ) pType;

        const sal_Int32 nElements        = (*(uno_Sequence **)pSource)->nElements;
        char * pSourceElements   = (char *)(*(uno_Sequence **)pSource)->elements;

        if( typelib_TypeClass_BYTE == pIndirectType->pType->eTypeClass )
        {
            // Byte sequences are optimized
            packByteSequence( (sal_Int8*)pSourceElements , nElements );
        }
        else
        {
            typelib_TypeDescription *pElementType = 0;
            TYPELIB_DANGER_GET( &pElementType, pIndirectType->pType );
            if( pElementType )
            {
                const sal_Int32 nElementSize     = pElementType->nSize;

                packCompressedSize( nElements );
                for ( sal_Int32 i = 0 ; i < nElements; i++ )
                {
                    bSuccess = bSuccess && pack( pSourceElements + (nElementSize*i) , pElementType );
                }
                TYPELIB_DANGER_RELEASE( pElementType );
            }
            else
            {
                bSuccess = sal_False;
                OUStringBuffer buf( 64 );
                buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
                buf.append( pIndirectType->pType->pTypeName );
                m_pBridgeImpl->addError( buf.makeStringAndClear() );
            }
        }
        break;
    }
    default:
        OSL_ASSERT( 0 );
    }
    return bSuccess;
}

} // end namespace bridges
<commit_msg>INTEGRATION: CWS pchfix02 (1.5.70); FILE MERGED 2006/09/01 17:17:42 kaib 1.5.70.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: urp_marshal.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 16:01:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_bridges.hxx"
#include <string.h>
#include <osl/diagnose.h>
#include <rtl/alloc.h>

#include <uno/any2.h>
#include <uno/sequence2.h>

#include "urp_marshal.hxx"

using namespace ::rtl;

using namespace ::com::sun::star::uno;

namespace bridges_urp {

static int g_nDetectLittleEndian = 1;
char g_bMarshalSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0];

Marshal::Marshal( urp_BridgeImpl *pBridgeImpl,
                  sal_Int32 nBufferSize,
                  urp_extractOidCallback callback) :
    m_nBufferSize( nBufferSize ),
    m_base( (sal_Int8*)rtl_allocateMemory( nBufferSize ) ),
    m_pos( m_base + 2*sizeof( sal_Int32 ) ),
    m_pBridgeImpl( pBridgeImpl ),
    m_callback( callback )
{}

Marshal::~Marshal( )
{
    rtl_freeMemory( m_base );
}

void Marshal::packOid( const ::rtl::OUString & oid )
{
    sal_uInt16 nIndex;
    if( oid.getLength() )
    {
        nIndex = m_pBridgeImpl->m_oidCacheOut.seek( oid );
        if( 0xffff == nIndex )
        {
            nIndex = m_pBridgeImpl->m_oidCacheOut.put( oid );
            packString( (void*)(&oid.pData) );
        }
        else
        {
            OUString dummy;
            packString( &dummy );
        }
    }
    else
    {
        // null reference
        nIndex = 0xffff;
        OUString dummy;
        packString( &dummy );
    }
    packInt16( &nIndex );
}

void Marshal::packTid( const ByteSequence & threadId, sal_Bool bIgnoreCache )
{

    sal_uInt16 nIndex = 0xffff;
    if( ! bIgnoreCache )
    {
        nIndex = m_pBridgeImpl->m_tidCacheOut.seek( threadId );
    }

    if( 0xffff == nIndex )
    {
        if( ! bIgnoreCache )
        {
            nIndex = m_pBridgeImpl->m_tidCacheOut.put( threadId );
        }
        packByteSequence( (sal_Int8*) threadId.getConstArray() ,threadId.getLength());
    }
    else
    {
        packByteSequence( 0 , 0 );
    }
    packInt16( &nIndex );
}

void Marshal::packType( void *pSource )
{
    typelib_TypeDescriptionReference *pRef =
        *(typelib_TypeDescriptionReference ** ) pSource;

    OSL_ASSERT( pRef );

    sal_uInt8 nTypeClass = ( sal_uInt8 ) pRef->eTypeClass;

    if( nTypeClass <= /* any*/ 14 )
    {
        packInt8( (sal_Int8*)&nTypeClass );
    }
    else
    {
        OUString sTypeName;
        sal_uInt16 nIndex = 0xffff;

        nIndex = m_pBridgeImpl->m_typeCacheOut.seek( *(Type*)&pRef );
        if( 0xffff == nIndex )
        {
            // put it into the cache
            nIndex = m_pBridgeImpl->m_typeCacheOut.put( *(Type*)&pRef );
            sTypeName = pRef->pTypeName;
            nTypeClass = nTypeClass | 0x80;
        }
        packInt8( &nTypeClass  );
        packInt16( &nIndex );
        if( 0x80 & nTypeClass )
        {
            packString( &sTypeName );
        }
    }
}

sal_Bool Marshal::packRecursive( void *pSource , typelib_TypeDescription *pType )
{
    sal_Bool bSuccess = sal_True;
    switch( pType->eTypeClass )
    {
    case typelib_TypeClass_EXCEPTION:
    case typelib_TypeClass_STRUCT:
    {
        typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription*)pType;

        if (pCompType->pBaseTypeDescription)
        {
            bSuccess = pack( pSource , (typelib_TypeDescription*) pCompType->pBaseTypeDescription );
        }

        // then construct members
        typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
        sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
        sal_Int32 nDescr = pCompType->nMembers;

        for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
        {
              typelib_TypeDescription * pMemberType = 0;
              TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] );
            if( pMemberType )
            {
                bSuccess = bSuccess && pack( (char*)pSource + pMemberOffsets[nPos] , pMemberType );
                TYPELIB_DANGER_RELEASE( pMemberType );
            }
            else
            {
                OUStringBuffer buf( 64 );
                buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
                buf.append( ppTypeRefs[nPos]->pTypeName );
                m_pBridgeImpl->addError( buf.makeStringAndClear() );
                bSuccess = sal_False;
            }
        }
        break;
    }
    case typelib_TypeClass_SEQUENCE:
    {
        typelib_IndirectTypeDescription *pIndirectType =
            ( typelib_IndirectTypeDescription* ) pType;

        const sal_Int32 nElements        = (*(uno_Sequence **)pSource)->nElements;
        char * pSourceElements   = (char *)(*(uno_Sequence **)pSource)->elements;

        if( typelib_TypeClass_BYTE == pIndirectType->pType->eTypeClass )
        {
            // Byte sequences are optimized
            packByteSequence( (sal_Int8*)pSourceElements , nElements );
        }
        else
        {
            typelib_TypeDescription *pElementType = 0;
            TYPELIB_DANGER_GET( &pElementType, pIndirectType->pType );
            if( pElementType )
            {
                const sal_Int32 nElementSize     = pElementType->nSize;

                packCompressedSize( nElements );
                for ( sal_Int32 i = 0 ; i < nElements; i++ )
                {
                    bSuccess = bSuccess && pack( pSourceElements + (nElementSize*i) , pElementType );
                }
                TYPELIB_DANGER_RELEASE( pElementType );
            }
            else
            {
                bSuccess = sal_False;
                OUStringBuffer buf( 64 );
                buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
                buf.append( pIndirectType->pType->pTypeName );
                m_pBridgeImpl->addError( buf.makeStringAndClear() );
            }
        }
        break;
    }
    default:
        OSL_ASSERT( 0 );
    }
    return bSuccess;
}

} // end namespace bridges
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

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.
-----------------------------------------------------------------------------
*/
#include "Ogre.h"
#include "RootWithoutRenderSystemFixture.h"
#include "OgreShaderGenerator.h"
#include "OgreShaderProgramManager.h"

#include "OgreShaderFFPTransform.h"
#include "OgreShaderFFPColour.h"

using namespace Ogre;

struct RTShaderSystem : public RootWithoutRenderSystemFixture
{
    std::unique_ptr<GpuProgramManager> gpuProgMgr;

    void SetUp()
    {
        RootWithoutRenderSystemFixture::SetUp();
        gpuProgMgr.reset(new GpuProgramManager());

        RTShader::ShaderGenerator::initialize();
        RTShader::ShaderGenerator::getSingleton().setTargetLanguage("glsl");
    }
    void TearDown()
    {
        RTShader::ShaderGenerator::destroy();
        gpuProgMgr.reset();
        RootWithoutRenderSystemFixture::TearDown();
    }
};

TEST_F(RTShaderSystem, createShaderBasedTechnique)
{
    auto& shaderGen = RTShader::ShaderGenerator::getSingleton();
    auto mat = MaterialManager::getSingleton().create("TestMat", RGN_DEFAULT);

    EXPECT_TRUE(shaderGen.createShaderBasedTechnique(mat->getTechniques()[0], "MyScheme"));

    EXPECT_EQ(mat->getTechniques().size(), size_t(1));
    shaderGen.validateMaterial("MyScheme", mat->getName(), mat->getGroup());
    EXPECT_EQ(mat->getTechniques().size(), size_t(2));

    auto newTech = mat->getTechniques()[1];

    EXPECT_EQ(newTech->getSchemeName(), "MyScheme");
    EXPECT_TRUE(newTech->getPasses()[0]->hasGpuProgram(GPT_VERTEX_PROGRAM));
    EXPECT_TRUE(newTech->getPasses()[0]->hasGpuProgram(GPT_FRAGMENT_PROGRAM));

    EXPECT_TRUE(shaderGen.removeShaderBasedTechnique(mat->getTechniques()[0], "MyScheme"));
}

TEST_F(RTShaderSystem, TargetRenderState)
{
    auto mat = MaterialManager::getSingleton().create("TestMat", RGN_DEFAULT);
    auto pass = mat->getTechniques()[0]->getPasses()[0];

    using namespace RTShader;
    auto& shaderGen = ShaderGenerator::getSingleton();

    TargetRenderState targetRenderState;
    targetRenderState.addSubRenderStateInstance(shaderGen.createSubRenderState<FFPTransform>());
    targetRenderState.addSubRenderStateInstance(shaderGen.createSubRenderState<FFPColour>());

    targetRenderState.acquirePrograms(pass);

    EXPECT_TRUE(pass->hasGpuProgram(GPT_VERTEX_PROGRAM));
    EXPECT_TRUE(pass->hasGpuProgram(GPT_FRAGMENT_PROGRAM));
}
<commit_msg>RTSS: add material serializer test<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

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.
-----------------------------------------------------------------------------
*/
#include "Ogre.h"
#include "RootWithoutRenderSystemFixture.h"
#include "OgreShaderGenerator.h"
#include "OgreShaderProgramManager.h"
#include "OgreShaderMaterialSerializerListener.h"

#include "OgreShaderFFPTransform.h"
#include "OgreShaderFFPColour.h"

using namespace Ogre;

struct RTShaderSystem : public RootWithoutRenderSystemFixture
{
    std::unique_ptr<GpuProgramManager> gpuProgMgr;

    void SetUp()
    {
        RootWithoutRenderSystemFixture::SetUp();
        gpuProgMgr.reset(new GpuProgramManager());

        RTShader::ShaderGenerator::initialize();
        RTShader::ShaderGenerator::getSingleton().setTargetLanguage("glsl");
    }
    void TearDown()
    {
        RTShader::ShaderGenerator::destroy();
        gpuProgMgr.reset();
        RootWithoutRenderSystemFixture::TearDown();
    }
};

TEST_F(RTShaderSystem, createShaderBasedTechnique)
{
    auto& shaderGen = RTShader::ShaderGenerator::getSingleton();
    auto mat = MaterialManager::getSingleton().create("TestMat", RGN_DEFAULT);

    EXPECT_TRUE(shaderGen.createShaderBasedTechnique(mat->getTechniques()[0], "MyScheme"));

    EXPECT_EQ(mat->getTechniques().size(), size_t(1));
    shaderGen.validateMaterial("MyScheme", mat->getName(), mat->getGroup());
    EXPECT_EQ(mat->getTechniques().size(), size_t(2));

    auto newTech = mat->getTechniques()[1];

    EXPECT_EQ(newTech->getSchemeName(), "MyScheme");
    EXPECT_TRUE(newTech->getPasses()[0]->hasGpuProgram(GPT_VERTEX_PROGRAM));
    EXPECT_TRUE(newTech->getPasses()[0]->hasGpuProgram(GPT_FRAGMENT_PROGRAM));

    EXPECT_TRUE(shaderGen.removeShaderBasedTechnique(mat->getTechniques()[0], "MyScheme"));
}

TEST_F(RTShaderSystem, MaterialSerializer)
{
    auto& shaderGen = RTShader::ShaderGenerator::getSingleton();
    auto mat = MaterialManager::getSingleton().create("TestMat", RGN_DEFAULT);

    shaderGen.createShaderBasedTechnique(mat->getTechniques()[0], "MyScheme");

    auto rstate = shaderGen.getRenderState("MyScheme", "TestMat", RGN_DEFAULT, 0);
    rstate->addTemplateSubRenderState(shaderGen.createSubRenderState<RTShader::FFPColour>());

    shaderGen.validateMaterial("MyScheme", mat->getName(), mat->getGroup());

    MaterialSerializer ser;
    ser.addListener(shaderGen.getMaterialSerializerListener());
    ser.queueForExport(mat);
    EXPECT_TRUE(ser.getQueuedAsString().find("colour_stage") != String::npos);
}

TEST_F(RTShaderSystem, TargetRenderState)
{
    auto mat = MaterialManager::getSingleton().create("TestMat", RGN_DEFAULT);
    auto pass = mat->getTechniques()[0]->getPasses()[0];

    using namespace RTShader;
    auto& shaderGen = ShaderGenerator::getSingleton();

    TargetRenderState targetRenderState;
    targetRenderState.addSubRenderStateInstance(shaderGen.createSubRenderState<FFPTransform>());
    targetRenderState.addSubRenderStateInstance(shaderGen.createSubRenderState<FFPColour>());

    targetRenderState.acquirePrograms(pass);

    EXPECT_TRUE(pass->hasGpuProgram(GPT_VERTEX_PROGRAM));
    EXPECT_TRUE(pass->hasGpuProgram(GPT_FRAGMENT_PROGRAM));
}
<|endoftext|>


<commit_before>#include <glow/FrameBufferObject.h>
#include <glow/Log.h>

#include <sstream>

using namespace glow;

ColorAttachment::ColorAttachment(GLenum attachment)
: _attachment(attachment)
{
}

GLenum ColorAttachment::attachment() const
{
	return _attachment;
}

TextureAttachment::TextureAttachment(Texture* texture, GLenum attachment)
: ColorAttachment(attachment)
, _texture(texture)
{
}

RenderBufferAttachment::RenderBufferAttachment(RenderBufferObject* renderBuffer, GLenum attachment)
: ColorAttachment(attachment)
, _renderBuffer(renderBuffer)
{
}

FrameBufferObject::FrameBufferObject()
: Object(genFrameBuffer())
, _target(GL_FRAMEBUFFER)
{
}

FrameBufferObject::~FrameBufferObject()
{
	if (_id) glDeleteFramebuffers(1, &_id);
}

GLuint FrameBufferObject::genFrameBuffer()
{
	GLuint id = 0;
	glGenFramebuffers(1, &id);
	return id;
}

void FrameBufferObject::bind()
{
	glBindFramebuffer(_target, _id);
}

void FrameBufferObject::bind(GLenum target)
{
	_target = target;
	glBindFramebuffer(target, _id);
}

void FrameBufferObject::unbind()
{
	glBindFramebuffer(_target, 0);
}

void FrameBufferObject::setParameter(GLenum pname, GLint param)
{
	bind();
	glFramebufferParameteri(_target, pname, param);
}

void FrameBufferObject::attachTexture(GLenum attachment, Texture* texture, GLint level)
{
	bind();
	glFramebufferTexture(_target, attachment, texture->id(), level);
	attach(new TextureAttachment(texture, attachment));
}

void FrameBufferObject::attachTexture1D(GLenum attachment, Texture* texture, GLint level)
{
	bind();
	glFramebufferTexture1D(_target, attachment, texture->target(), texture->id(), level);
	attach(new TextureAttachment(texture, attachment));
}

void FrameBufferObject::attachTexture2D(GLenum attachment, Texture* texture, GLint level)
{
	bind();
	glFramebufferTexture2D(_target, attachment, texture->target(), texture->id(), level);
	attach(new TextureAttachment(texture, attachment));
}

void FrameBufferObject::attachTextureLayer(GLenum attachment, Texture* texture, GLint level, GLint layer)
{
	bind();
	glFramebufferTextureLayer(_target, attachment, texture->id(), level, layer);
	attach(new TextureAttachment(texture, attachment));
}

void FrameBufferObject::attachRenderBuffer(GLenum attachment, RenderBufferObject* renderBuffer)
{
	bind();
	glFramebufferRenderbuffer(_target, attachment, GL_RENDERBUFFER, renderBuffer->id());
	attach(new RenderBufferAttachment(renderBuffer, attachment));
}

void FrameBufferObject::attach(ColorAttachment* attachment)
{
	_attachments[attachment->attachment()] = attachment;
}

void FrameBufferObject::blit(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint destX0, GLint destY0, GLint destX1, GLint destY1, GLbitfield mask, GLenum filter)
{
	glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, destX0, destY0, destX1, destY1, mask, filter);
}

GLenum FrameBufferObject::checkStatus()
{
	bind();
	return glCheckFramebufferStatus(_target);
}

std::string FrameBufferObject::statusString()
{
	return statusString(checkStatus());
}

std::string FrameBufferObject::statusString(GLenum status)
{
	switch (status)
	{
		case GL_FRAMEBUFFER_COMPLETE:
			return "GL_FRAMEBUFFER_COMPLETE";
		case GL_FRAMEBUFFER_UNDEFINED:
			return "GL_FRAMEBUFFER_UNDEFINED";
		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
			return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
			return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
			return "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER";
		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
			return "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER";
		case GL_FRAMEBUFFER_UNSUPPORTED:
			return "GL_FRAMEBUFFER_UNSUPPORTED";
		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
			return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
		case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
			return "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS";
		default:
			return "unknown framebuffer error";
	}
}

void FrameBufferObject::printStatus(bool onlyErrors)
{
	GLenum status = checkStatus();

	if (onlyErrors && status == GL_FRAMEBUFFER_COMPLETE) return;

	if (status == GL_FRAMEBUFFER_COMPLETE)
	{
		log() << statusString(GL_FRAMEBUFFER_COMPLETE);
	}
	else
	{
		std::stringstream ss;
		ss.flags(std::ios::hex | std::ios::showbase);
		ss << status;

		error() << statusString(status) << " (" << ss.str() << ")";
	}
}
<commit_msg>bind render buffer when attached to framebufferobject<commit_after>#include <glow/FrameBufferObject.h>
#include <glow/Log.h>

#include <sstream>

using namespace glow;

ColorAttachment::ColorAttachment(GLenum attachment)
: _attachment(attachment)
{
}

GLenum ColorAttachment::attachment() const
{
	return _attachment;
}

TextureAttachment::TextureAttachment(Texture* texture, GLenum attachment)
: ColorAttachment(attachment)
, _texture(texture)
{
}

RenderBufferAttachment::RenderBufferAttachment(RenderBufferObject* renderBuffer, GLenum attachment)
: ColorAttachment(attachment)
, _renderBuffer(renderBuffer)
{
}

FrameBufferObject::FrameBufferObject()
: Object(genFrameBuffer())
, _target(GL_FRAMEBUFFER)
{
}

FrameBufferObject::~FrameBufferObject()
{
	if (_id) glDeleteFramebuffers(1, &_id);
}

GLuint FrameBufferObject::genFrameBuffer()
{
	GLuint id = 0;
	glGenFramebuffers(1, &id);
	return id;
}

void FrameBufferObject::bind()
{
	glBindFramebuffer(_target, _id);
}

void FrameBufferObject::bind(GLenum target)
{
	_target = target;
	glBindFramebuffer(target, _id);
}

void FrameBufferObject::unbind()
{
	glBindFramebuffer(_target, 0);
}

void FrameBufferObject::setParameter(GLenum pname, GLint param)
{
	bind();
	glFramebufferParameteri(_target, pname, param);
}

void FrameBufferObject::attachTexture(GLenum attachment, Texture* texture, GLint level)
{
	bind();
	glFramebufferTexture(_target, attachment, texture->id(), level);
	attach(new TextureAttachment(texture, attachment));
}

void FrameBufferObject::attachTexture1D(GLenum attachment, Texture* texture, GLint level)
{
	bind();
	glFramebufferTexture1D(_target, attachment, texture->target(), texture->id(), level);
	attach(new TextureAttachment(texture, attachment));
}

void FrameBufferObject::attachTexture2D(GLenum attachment, Texture* texture, GLint level)
{
	bind();
	glFramebufferTexture2D(_target, attachment, texture->target(), texture->id(), level);
	attach(new TextureAttachment(texture, attachment));
}

void FrameBufferObject::attachTextureLayer(GLenum attachment, Texture* texture, GLint level, GLint layer)
{
	bind();
	glFramebufferTextureLayer(_target, attachment, texture->id(), level, layer);
	attach(new TextureAttachment(texture, attachment));
}

void FrameBufferObject::attachRenderBuffer(GLenum attachment, RenderBufferObject* renderBuffer)
{
	bind();
	renderBuffer->bind();
	glFramebufferRenderbuffer(_target, attachment, GL_RENDERBUFFER, renderBuffer->id());
	attach(new RenderBufferAttachment(renderBuffer, attachment));
}

void FrameBufferObject::attach(ColorAttachment* attachment)
{
	_attachments[attachment->attachment()] = attachment;
}

void FrameBufferObject::blit(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint destX0, GLint destY0, GLint destX1, GLint destY1, GLbitfield mask, GLenum filter)
{
	glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, destX0, destY0, destX1, destY1, mask, filter);
}

GLenum FrameBufferObject::checkStatus()
{
	bind();
	return glCheckFramebufferStatus(_target);
}

std::string FrameBufferObject::statusString()
{
	return statusString(checkStatus());
}

std::string FrameBufferObject::statusString(GLenum status)
{
	switch (status)
	{
		case GL_FRAMEBUFFER_COMPLETE:
			return "GL_FRAMEBUFFER_COMPLETE";
		case GL_FRAMEBUFFER_UNDEFINED:
			return "GL_FRAMEBUFFER_UNDEFINED";
		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
			return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
			return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
			return "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER";
		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
			return "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER";
		case GL_FRAMEBUFFER_UNSUPPORTED:
			return "GL_FRAMEBUFFER_UNSUPPORTED";
		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
			return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
		case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
			return "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS";
		default:
			return "unknown framebuffer error";
	}
}

void FrameBufferObject::printStatus(bool onlyErrors)
{
	GLenum status = checkStatus();

	if (onlyErrors && status == GL_FRAMEBUFFER_COMPLETE) return;

	if (status == GL_FRAMEBUFFER_COMPLETE)
	{
		log() << statusString(GL_FRAMEBUFFER_COMPLETE);
	}
	else
	{
		std::stringstream ss;
		ss.flags(std::ios::hex | std::ios::showbase);
		ss << status;

		error() << statusString(status) << " (" << ss.str() << ")";
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 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.

#include "chrome/browser/tab_contents/web_contents_view_gtk.h"

#include <gdk/gdk.h>
#include <gtk/gtk.h>

#include "base/gfx/point.h"
#include "base/gfx/rect.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/tab_contents/render_view_context_menu_gtk.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/browser/tab_contents/web_contents.h"

#include "webkit/glue/webinputevent.h"

namespace {

// Called when the content view gtk widget is tabbed to. We always return true
// and grab focus if we don't have it. The call to SetInitialFocus(bool)
// forwards the tab to webkit. We leave focus via TakeFocus().
// We cast the WebContents to a TabContents because SetInitialFocus is public
// in TabContents and protected in WebContents.
gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus,
                 TabContents* tab_contents) {
  if (GTK_WIDGET_HAS_FOCUS(widget))
    return TRUE;

  gtk_widget_grab_focus(widget);
  bool reverse = focus == GTK_DIR_TAB_BACKWARD;
  tab_contents->SetInitialFocus(reverse);
  return TRUE;
}

// Called when the mouse leaves the widget. We notify our delegate.
gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event,
                       WebContents* web_contents) {
  if (web_contents->delegate())
    web_contents->delegate()->ContentsMouseEvent(web_contents, false);
  return FALSE;
}

// Called when the mouse moves within the widget. We notify our delegate.
gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event,
                     WebContents* web_contents) {
  if (web_contents->delegate())
    web_contents->delegate()->ContentsMouseEvent(web_contents, true);
  return FALSE;
}

// Callback used in WebContentsViewGtk::CreateViewForWidget().
void RemoveWidget(GtkWidget* widget, gpointer container) {
  gtk_container_remove(GTK_CONTAINER(container), widget);
}

}  // namespace

// static
WebContentsView* WebContentsView::Create(WebContents* web_contents) {
  return new WebContentsViewGtk(web_contents);
}

WebContentsViewGtk::WebContentsViewGtk(WebContents* web_contents)
    : WebContentsView(web_contents),
      vbox_(gtk_vbox_new(FALSE, 0)) {
}

WebContentsViewGtk::~WebContentsViewGtk() {
  vbox_.Destroy();
}

void WebContentsViewGtk::CreateView() {
  NOTIMPLEMENTED();
}

RenderWidgetHostView* WebContentsViewGtk::CreateViewForWidget(
    RenderWidgetHost* render_widget_host) {
  DCHECK(!render_widget_host->view());
  RenderWidgetHostViewGtk* view =
      new RenderWidgetHostViewGtk(render_widget_host);
  view->InitAsChild();
  content_view_ = view->native_view();
  g_signal_connect(content_view_, "focus",
                   G_CALLBACK(OnFocus), web_contents());
  g_signal_connect(view->native_view(), "leave-notify-event",
                   G_CALLBACK(OnLeaveNotify), web_contents());
  g_signal_connect(view->native_view(), "motion-notify-event",
                   G_CALLBACK(OnMouseMove), web_contents());
  gtk_widget_add_events(view->native_view(), GDK_LEAVE_NOTIFY_MASK |
                        GDK_POINTER_MOTION_MASK);
  gtk_container_foreach(GTK_CONTAINER(vbox_.get()), RemoveWidget, vbox_.get());
  gtk_box_pack_start(GTK_BOX(vbox_.get()), content_view_, TRUE, TRUE, 0);
  return view;
}

gfx::NativeView WebContentsViewGtk::GetNativeView() const {
  return vbox_.get();
}

gfx::NativeView WebContentsViewGtk::GetContentNativeView() const {
  return content_view_;
}

gfx::NativeWindow WebContentsViewGtk::GetTopLevelNativeWindow() const {
  return GTK_WINDOW(gtk_widget_get_toplevel(vbox_.get()));
}

void WebContentsViewGtk::GetContainerBounds(gfx::Rect* out) const {
  // This is used for positioning the download shelf arrow animation,
  // as well as sizing some other widgets in Windows.  In GTK the size is
  // managed for us, so it appears to be only used for the download shelf
  // animation.
  out->SetRect(vbox_.get()->allocation.x, vbox_.get()->allocation.y,
               vbox_.get()->allocation.width, vbox_.get()->allocation.height);
}

void WebContentsViewGtk::OnContentsDestroy() {
  // TODO(estade): Windows uses this function cancel pending drag-n-drop drags.
  // We don't have drags yet, so do nothing for now.
}

void WebContentsViewGtk::SetPageTitle(const std::wstring& title) {
  // Set the window name to include the page title so it's easier to spot
  // when debugging (e.g. via xwininfo -tree).
  if (content_view_ && content_view_->window)
    gdk_window_set_title(content_view_->window, WideToUTF8(title).c_str());
}

void WebContentsViewGtk::Invalidate() {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::SizeContents(const gfx::Size& size) {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::FindInPage(const Browser& browser,
                                    bool find_next, bool forward_direction) {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::HideFindBar(bool end_session) {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::ReparentFindWindow(Browser* new_browser) const {
  NOTIMPLEMENTED();
}

bool WebContentsViewGtk::GetFindBarWindowInfo(gfx::Point* position,
                                              bool* fully_visible) const {
  NOTIMPLEMENTED();
  return false;
}

void WebContentsViewGtk::SetInitialFocus() {
  if (web_contents()->FocusLocationBarByDefault())
    web_contents()->delegate()->SetFocusToLocationBar();
  else
    gtk_widget_grab_focus(content_view_);
}

void WebContentsViewGtk::StoreFocus() {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::RestoreFocus() {
  // TODO(estade): implement this function.
  // For now just assume we are viewing the tab for the first time.
  SetInitialFocus();
  NOTIMPLEMENTED() << " --  need to restore the focus position on this page.";
}

void WebContentsViewGtk::UpdateDragCursor(bool is_drop_target) {
  NOTIMPLEMENTED();
}

// This is called when we the renderer asks us to take focus back (i.e., it has
// iterated past the last focusable element on the page).
void WebContentsViewGtk::TakeFocus(bool reverse) {
  web_contents()->delegate()->SetFocusToLocationBar();
}

void WebContentsViewGtk::HandleKeyboardEvent(
    const NativeWebKeyboardEvent& event) {
  // This may be an accelerator. Pass it on to our browser window to handle.
  GtkWindow* window = GetTopLevelNativeWindow();
  BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>(
            g_object_get_data(G_OBJECT(window), "browser_window_gtk"));
  browser_window->HandleAccelerator(event.os_event->keyval,
      static_cast<GdkModifierType>(event.os_event->state));
}

void WebContentsViewGtk::OnFindReply(int request_id,
                                     int number_of_matches,
                                     const gfx::Rect& selection_rect,
                                     int active_match_ordinal,
                                     bool final_update) {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::ShowContextMenu(const ContextMenuParams& params) {
  context_menu_.reset(new RenderViewContextMenuGtk(web_contents(), params));
  context_menu_->Popup();
}

void WebContentsViewGtk::StartDragging(const WebDropData& drop_data) {
  NOTIMPLEMENTED();

  // Until we have d'n'd implemented, just immediately pretend we're
  // already done with the drag and drop so we don't get stuck
  // thinking we're in mid-drag.
  // TODO(port): remove me when the above NOTIMPLEMENTED is fixed.
  if (web_contents()->render_view_host())
    web_contents()->render_view_host()->DragSourceSystemDragEnded();
}

WebContents* WebContentsViewGtk::CreateNewWindowInternal(
    int route_id,
    base::WaitableEvent* modal_dialog_event) {
  NOTIMPLEMENTED();
  return NULL;
}

void WebContentsViewGtk::ShowCreatedWindowInternal(
    WebContents* new_web_contents,
    WindowOpenDisposition disposition,
    const gfx::Rect& initial_pos,
    bool user_gesture) {
  NOTIMPLEMENTED();
}
<commit_msg>Fix crash when trying to handle keyboard accelerators while the current tab contents is no longer in the view hierarchy (ie., it got switched out).<commit_after>// Copyright (c) 2009 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.

#include "chrome/browser/tab_contents/web_contents_view_gtk.h"

#include <gdk/gdk.h>
#include <gtk/gtk.h>

#include "base/gfx/point.h"
#include "base/gfx/rect.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/tab_contents/render_view_context_menu_gtk.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/browser/tab_contents/web_contents.h"

#include "webkit/glue/webinputevent.h"

namespace {

// Called when the content view gtk widget is tabbed to. We always return true
// and grab focus if we don't have it. The call to SetInitialFocus(bool)
// forwards the tab to webkit. We leave focus via TakeFocus().
// We cast the WebContents to a TabContents because SetInitialFocus is public
// in TabContents and protected in WebContents.
gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus,
                 TabContents* tab_contents) {
  if (GTK_WIDGET_HAS_FOCUS(widget))
    return TRUE;

  gtk_widget_grab_focus(widget);
  bool reverse = focus == GTK_DIR_TAB_BACKWARD;
  tab_contents->SetInitialFocus(reverse);
  return TRUE;
}

// Called when the mouse leaves the widget. We notify our delegate.
gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event,
                       WebContents* web_contents) {
  if (web_contents->delegate())
    web_contents->delegate()->ContentsMouseEvent(web_contents, false);
  return FALSE;
}

// Called when the mouse moves within the widget. We notify our delegate.
gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event,
                     WebContents* web_contents) {
  if (web_contents->delegate())
    web_contents->delegate()->ContentsMouseEvent(web_contents, true);
  return FALSE;
}

// Callback used in WebContentsViewGtk::CreateViewForWidget().
void RemoveWidget(GtkWidget* widget, gpointer container) {
  gtk_container_remove(GTK_CONTAINER(container), widget);
}

}  // namespace

// static
WebContentsView* WebContentsView::Create(WebContents* web_contents) {
  return new WebContentsViewGtk(web_contents);
}

WebContentsViewGtk::WebContentsViewGtk(WebContents* web_contents)
    : WebContentsView(web_contents),
      vbox_(gtk_vbox_new(FALSE, 0)) {
}

WebContentsViewGtk::~WebContentsViewGtk() {
  vbox_.Destroy();
}

void WebContentsViewGtk::CreateView() {
  NOTIMPLEMENTED();
}

RenderWidgetHostView* WebContentsViewGtk::CreateViewForWidget(
    RenderWidgetHost* render_widget_host) {
  DCHECK(!render_widget_host->view());
  RenderWidgetHostViewGtk* view =
      new RenderWidgetHostViewGtk(render_widget_host);
  view->InitAsChild();
  content_view_ = view->native_view();
  g_signal_connect(content_view_, "focus",
                   G_CALLBACK(OnFocus), web_contents());
  g_signal_connect(view->native_view(), "leave-notify-event",
                   G_CALLBACK(OnLeaveNotify), web_contents());
  g_signal_connect(view->native_view(), "motion-notify-event",
                   G_CALLBACK(OnMouseMove), web_contents());
  gtk_widget_add_events(view->native_view(), GDK_LEAVE_NOTIFY_MASK |
                        GDK_POINTER_MOTION_MASK);
  gtk_container_foreach(GTK_CONTAINER(vbox_.get()), RemoveWidget, vbox_.get());
  gtk_box_pack_start(GTK_BOX(vbox_.get()), content_view_, TRUE, TRUE, 0);
  return view;
}

gfx::NativeView WebContentsViewGtk::GetNativeView() const {
  return vbox_.get();
}

gfx::NativeView WebContentsViewGtk::GetContentNativeView() const {
  return content_view_;
}

gfx::NativeWindow WebContentsViewGtk::GetTopLevelNativeWindow() const {
  GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW);
  return window ? GTK_WINDOW(window) : NULL;
}

void WebContentsViewGtk::GetContainerBounds(gfx::Rect* out) const {
  // This is used for positioning the download shelf arrow animation,
  // as well as sizing some other widgets in Windows.  In GTK the size is
  // managed for us, so it appears to be only used for the download shelf
  // animation.
  out->SetRect(vbox_.get()->allocation.x, vbox_.get()->allocation.y,
               vbox_.get()->allocation.width, vbox_.get()->allocation.height);
}

void WebContentsViewGtk::OnContentsDestroy() {
  // TODO(estade): Windows uses this function cancel pending drag-n-drop drags.
  // We don't have drags yet, so do nothing for now.
}

void WebContentsViewGtk::SetPageTitle(const std::wstring& title) {
  // Set the window name to include the page title so it's easier to spot
  // when debugging (e.g. via xwininfo -tree).
  if (content_view_ && content_view_->window)
    gdk_window_set_title(content_view_->window, WideToUTF8(title).c_str());
}

void WebContentsViewGtk::Invalidate() {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::SizeContents(const gfx::Size& size) {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::FindInPage(const Browser& browser,
                                    bool find_next, bool forward_direction) {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::HideFindBar(bool end_session) {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::ReparentFindWindow(Browser* new_browser) const {
  NOTIMPLEMENTED();
}

bool WebContentsViewGtk::GetFindBarWindowInfo(gfx::Point* position,
                                              bool* fully_visible) const {
  NOTIMPLEMENTED();
  return false;
}

void WebContentsViewGtk::SetInitialFocus() {
  if (web_contents()->FocusLocationBarByDefault())
    web_contents()->delegate()->SetFocusToLocationBar();
  else
    gtk_widget_grab_focus(content_view_);
}

void WebContentsViewGtk::StoreFocus() {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::RestoreFocus() {
  // TODO(estade): implement this function.
  // For now just assume we are viewing the tab for the first time.
  SetInitialFocus();
  NOTIMPLEMENTED() << " --  need to restore the focus position on this page.";
}

void WebContentsViewGtk::UpdateDragCursor(bool is_drop_target) {
  NOTIMPLEMENTED();
}

// This is called when we the renderer asks us to take focus back (i.e., it has
// iterated past the last focusable element on the page).
void WebContentsViewGtk::TakeFocus(bool reverse) {
  web_contents()->delegate()->SetFocusToLocationBar();
}

void WebContentsViewGtk::HandleKeyboardEvent(
    const NativeWebKeyboardEvent& event) {
  // This may be an accelerator. Try to pass it on to our browser window
  // to handle.
  GtkWindow* window = GetTopLevelNativeWindow();
  // It's possible to not be associated with a window at the time when we're
  // handling the keyboard event (e.g., the user opened a new tab in the time).
  // What we really want to do is get whatever currently has focus and have
  // that handle the accelerator.  TODO(tc): Consider walking
  // gtk_window_list_toplevels to find what has focus and if that's a browser
  // window, forward the event.
  if (!window)
    return;

  BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>(
      g_object_get_data(G_OBJECT(window), "browser_window_gtk"));
  DCHECK(browser_window);
  browser_window->HandleAccelerator(event.os_event->keyval,
      static_cast<GdkModifierType>(event.os_event->state));
}

void WebContentsViewGtk::OnFindReply(int request_id,
                                     int number_of_matches,
                                     const gfx::Rect& selection_rect,
                                     int active_match_ordinal,
                                     bool final_update) {
  NOTIMPLEMENTED();
}

void WebContentsViewGtk::ShowContextMenu(const ContextMenuParams& params) {
  context_menu_.reset(new RenderViewContextMenuGtk(web_contents(), params));
  context_menu_->Popup();
}

void WebContentsViewGtk::StartDragging(const WebDropData& drop_data) {
  NOTIMPLEMENTED();

  // Until we have d'n'd implemented, just immediately pretend we're
  // already done with the drag and drop so we don't get stuck
  // thinking we're in mid-drag.
  // TODO(port): remove me when the above NOTIMPLEMENTED is fixed.
  if (web_contents()->render_view_host())
    web_contents()->render_view_host()->DragSourceSystemDragEnded();
}

WebContents* WebContentsViewGtk::CreateNewWindowInternal(
    int route_id,
    base::WaitableEvent* modal_dialog_event) {
  NOTIMPLEMENTED();
  return NULL;
}

void WebContentsViewGtk::ShowCreatedWindowInternal(
    WebContents* new_web_contents,
    WindowOpenDisposition disposition,
    const gfx::Rect& initial_pos,
    bool user_gesture) {
  NOTIMPLEMENTED();
}
<|endoftext|>


<commit_before>//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the llc code generator driver. It provides a convenient
// command-line interface for generating native assembly-language code
// or C code, given LLVM bytecode.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/System/Signals.h"
#include "llvm/Config/config.h"
#include <fstream>
#include <iostream>
#include <memory>

using namespace llvm;

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));

static cl::opt<bool> Fast("fast",
      cl::desc("Generate code quickly, potentially sacrificing code quality"));

static cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser>
MArch("march", cl::desc("Architecture to generate code for:"));

static cl::opt<std::string>
MCPU("mcpu",
  cl::desc("Target a specific cpu type (-mcpu=help for details)"),
  cl::value_desc("cpu-name"),
  cl::init(""));

static cl::list<std::string>
MAttrs("mattr",
  cl::CommaSeparated,
  cl::desc("Target specific attributes (-mattr=help for details)"),
  cl::value_desc("a1,+a2,-a3,..."));

cl::opt<TargetMachine::CodeGenFileType>
FileType("filetype", cl::init(TargetMachine::AssemblyFile),
  cl::desc("Choose a file type (not all types are supported by all targets):"),
  cl::values(
       clEnumValN(TargetMachine::AssemblyFile,    "asm",
                  "  Emit an assembly ('.s') file"),
       clEnumValN(TargetMachine::ObjectFile,    "obj",
                  "  Emit a native object ('.o') file [experimental]"),
       clEnumValN(TargetMachine::DynamicLibrary, "dynlib",
                  "  Emit a native dynamic library ('.so') file"),
       clEnumValEnd));

// The LLCPassList is populated with passes that were registered using
//  PassInfo::LLC by the FilteredPassNameParser:
cl::list<const PassInfo*, bool, FilteredPassNameParser<PassInfo::LLC> >
LLCPassList(cl::desc("Passes Available"));

cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
                       cl::desc("Do not verify input module"));

// GetFileNameRoot - Helper function to get the basename of a filename.
static inline std::string
GetFileNameRoot(const std::string &InputFilename) {
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if ((Len > 2) &&
      IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  try {
    cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
    sys::PrintStackTraceOnErrorSignal();

    // Load the module to be compiled...
    std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
    if (M.get() == 0) {
      std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
      return 1;
    }
    Module &mod = *M.get();

    // Allocate target machine.  First, check whether the user has
    // explicitly specified an architecture to compile for.
    TargetMachine* (*TargetMachineAllocator)(const Module&,
                                             IntrinsicLowering *) = 0;
    if (MArch == 0) {
      std::string Err;
      MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
      if (MArch == 0) {
        std::cerr << argv[0] << ": error auto-selecting target for module '"
                  << Err << "'.  Please use the -march option to explicitly "
                  << "pick a target.\n";
        return 1;
      }
    }

    // Package up features to be passed to target/subtarget
    std::string FeaturesStr;
    if (MCPU.size() || MAttrs.size()) {
      SubtargetFeatures Features;
      Features.setCPU(MCPU);
      for (unsigned i = 0; i != MAttrs.size(); ++i)
        Features.AddFeature(MAttrs[i]);
      FeaturesStr = Features.getString();
    }

    std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0, FeaturesStr));
    assert(target.get() && "Could not allocate target machine!");
    TargetMachine &Target = *target.get();
    const TargetData &TD = Target.getTargetData();

    // Build up all of the passes that we want to do to the module...
    PassManager Passes;
    Passes.add(new TargetData(TD));

    // Create a new pass for each one specified on the command line
    for (unsigned i = 0; i < LLCPassList.size(); ++i) {
      const PassInfo *aPass = LLCPassList[i];

      if (aPass->getNormalCtor()) {
        Pass *P = aPass->getNormalCtor()();
        Passes.add(P);
      } else {
        std::cerr << argv[0] << ": cannot create pass: "
                  << aPass->getPassName() << "\n";
      }
    }

#ifndef NDEBUG
    if(!NoVerify)
      Passes.add(createVerifierPass());
#endif

    // Figure out where we are going to send the output...
    std::ostream *Out = 0;
    if (OutputFilename != "") {
      if (OutputFilename != "-") {
        // Specified an output filename?
        if (!Force && std::ifstream(OutputFilename.c_str())) {
          // If force is not specified, make sure not to overwrite a file!
          std::cerr << argv[0] << ": error opening '" << OutputFilename
                    << "': file exists!\n"
                    << "Use -f command line argument to force output\n";
          return 1;
        }
        Out = new std::ofstream(OutputFilename.c_str());

        // Make sure that the Out file gets unlinked from the disk if we get a
        // SIGINT
        sys::RemoveFileOnSignal(sys::Path(OutputFilename));
      } else {
        Out = &std::cout;
      }
    } else {
      if (InputFilename == "-") {
        OutputFilename = "-";
        Out = &std::cout;
      } else {
        OutputFilename = GetFileNameRoot(InputFilename);

        switch (FileType) {
        case TargetMachine::AssemblyFile:
          if (MArch->Name[0] != 'c' || MArch->Name[1] != 0)  // not CBE
            OutputFilename += ".s";
          else
            OutputFilename += ".cbe.c";
          break;
        case TargetMachine::ObjectFile:
          OutputFilename += ".o";
          break;
        case TargetMachine::DynamicLibrary:
          OutputFilename += LTDL_SHLIB_EXT;
          break;
        }

        if (!Force && std::ifstream(OutputFilename.c_str())) {
          // If force is not specified, make sure not to overwrite a file!
          std::cerr << argv[0] << ": error opening '" << OutputFilename
                    << "': file exists!\n"
                    << "Use -f command line argument to force output\n";
          return 1;
        }

        Out = new std::ofstream(OutputFilename.c_str());
        if (!Out->good()) {
          std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
          delete Out;
          return 1;
        }

        // Make sure that the Out file gets unlinked from the disk if we get a
        // SIGINT
        sys::RemoveFileOnSignal(sys::Path(OutputFilename));
      }
    }

    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
      std::cerr << argv[0] << ": target '" << Target.getName()
                << "' does not support generation of this file type!\n";
      if (Out != &std::cout) delete Out;
      // And the Out file is empty and useless, so remove it now.
      std::remove(OutputFilename.c_str());
      return 1;
    } else {
      // Run our queue of passes all at once now, efficiently.
      Passes.run(*M.get());
    }

    // Delete the ostream if it's not a stdout stream
    if (Out != &std::cout) delete Out;

    return 0;
  } catch (const std::string& msg) {
    std::cerr << argv[0] << ": " << msg << "\n";
  } catch (...) {
    std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
  }
  return 1;
}
<commit_msg>provide an option to override the target triple in a module from the command line.<commit_after>//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the llc code generator driver. It provides a convenient
// command-line interface for generating native assembly-language code
// or C code, given LLVM bytecode.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/System/Signals.h"
#include "llvm/Config/config.h"
#include <fstream>
#include <iostream>
#include <memory>

using namespace llvm;

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));

static cl::opt<bool> Fast("fast",
      cl::desc("Generate code quickly, potentially sacrificing code quality"));

static cl::opt<std::string>
TargetTriple("triple", cl::desc("Override target triple for module"));

static cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser>
MArch("march", cl::desc("Architecture to generate code for:"));

static cl::opt<std::string>
MCPU("mcpu",
  cl::desc("Target a specific cpu type (-mcpu=help for details)"),
  cl::value_desc("cpu-name"),
  cl::init(""));

static cl::list<std::string>
MAttrs("mattr",
  cl::CommaSeparated,
  cl::desc("Target specific attributes (-mattr=help for details)"),
  cl::value_desc("a1,+a2,-a3,..."));

cl::opt<TargetMachine::CodeGenFileType>
FileType("filetype", cl::init(TargetMachine::AssemblyFile),
  cl::desc("Choose a file type (not all types are supported by all targets):"),
  cl::values(
       clEnumValN(TargetMachine::AssemblyFile,    "asm",
                  "  Emit an assembly ('.s') file"),
       clEnumValN(TargetMachine::ObjectFile,    "obj",
                  "  Emit a native object ('.o') file [experimental]"),
       clEnumValN(TargetMachine::DynamicLibrary, "dynlib",
                  "  Emit a native dynamic library ('.so') file"),
       clEnumValEnd));

// The LLCPassList is populated with passes that were registered using
//  PassInfo::LLC by the FilteredPassNameParser:
cl::list<const PassInfo*, bool, FilteredPassNameParser<PassInfo::LLC> >
LLCPassList(cl::desc("Passes Available"));

cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
                       cl::desc("Do not verify input module"));

// GetFileNameRoot - Helper function to get the basename of a filename.
static inline std::string
GetFileNameRoot(const std::string &InputFilename) {
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if ((Len > 2) &&
      IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  try {
    cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
    sys::PrintStackTraceOnErrorSignal();

    // Load the module to be compiled...
    std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
    if (M.get() == 0) {
      std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
      return 1;
    }
    Module &mod = *M.get();

    // If we are supposed to override the target triple, do so now.
    if (!TargetTriple.empty())
      mod.setTargetTriple(TargetTriple);

    // Allocate target machine.  First, check whether the user has
    // explicitly specified an architecture to compile for.
    TargetMachine* (*TargetMachineAllocator)(const Module&,
                                             IntrinsicLowering *) = 0;
    if (MArch == 0) {
      std::string Err;
      MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
      if (MArch == 0) {
        std::cerr << argv[0] << ": error auto-selecting target for module '"
                  << Err << "'.  Please use the -march option to explicitly "
                  << "pick a target.\n";
        return 1;
      }
    }

    // Package up features to be passed to target/subtarget
    std::string FeaturesStr;
    if (MCPU.size() || MAttrs.size()) {
      SubtargetFeatures Features;
      Features.setCPU(MCPU);
      for (unsigned i = 0; i != MAttrs.size(); ++i)
        Features.AddFeature(MAttrs[i]);
      FeaturesStr = Features.getString();
    }

    std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0, FeaturesStr));
    assert(target.get() && "Could not allocate target machine!");
    TargetMachine &Target = *target.get();
    const TargetData &TD = Target.getTargetData();

    // Build up all of the passes that we want to do to the module...
    PassManager Passes;
    Passes.add(new TargetData(TD));

    // Create a new pass for each one specified on the command line
    for (unsigned i = 0; i < LLCPassList.size(); ++i) {
      const PassInfo *aPass = LLCPassList[i];

      if (aPass->getNormalCtor()) {
        Pass *P = aPass->getNormalCtor()();
        Passes.add(P);
      } else {
        std::cerr << argv[0] << ": cannot create pass: "
                  << aPass->getPassName() << "\n";
      }
    }

#ifndef NDEBUG
    if(!NoVerify)
      Passes.add(createVerifierPass());
#endif

    // Figure out where we are going to send the output...
    std::ostream *Out = 0;
    if (OutputFilename != "") {
      if (OutputFilename != "-") {
        // Specified an output filename?
        if (!Force && std::ifstream(OutputFilename.c_str())) {
          // If force is not specified, make sure not to overwrite a file!
          std::cerr << argv[0] << ": error opening '" << OutputFilename
                    << "': file exists!\n"
                    << "Use -f command line argument to force output\n";
          return 1;
        }
        Out = new std::ofstream(OutputFilename.c_str());

        // Make sure that the Out file gets unlinked from the disk if we get a
        // SIGINT
        sys::RemoveFileOnSignal(sys::Path(OutputFilename));
      } else {
        Out = &std::cout;
      }
    } else {
      if (InputFilename == "-") {
        OutputFilename = "-";
        Out = &std::cout;
      } else {
        OutputFilename = GetFileNameRoot(InputFilename);

        switch (FileType) {
        case TargetMachine::AssemblyFile:
          if (MArch->Name[0] != 'c' || MArch->Name[1] != 0)  // not CBE
            OutputFilename += ".s";
          else
            OutputFilename += ".cbe.c";
          break;
        case TargetMachine::ObjectFile:
          OutputFilename += ".o";
          break;
        case TargetMachine::DynamicLibrary:
          OutputFilename += LTDL_SHLIB_EXT;
          break;
        }

        if (!Force && std::ifstream(OutputFilename.c_str())) {
          // If force is not specified, make sure not to overwrite a file!
          std::cerr << argv[0] << ": error opening '" << OutputFilename
                    << "': file exists!\n"
                    << "Use -f command line argument to force output\n";
          return 1;
        }

        Out = new std::ofstream(OutputFilename.c_str());
        if (!Out->good()) {
          std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
          delete Out;
          return 1;
        }

        // Make sure that the Out file gets unlinked from the disk if we get a
        // SIGINT
        sys::RemoveFileOnSignal(sys::Path(OutputFilename));
      }
    }

    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
      std::cerr << argv[0] << ": target '" << Target.getName()
                << "' does not support generation of this file type!\n";
      if (Out != &std::cout) delete Out;
      // And the Out file is empty and useless, so remove it now.
      std::remove(OutputFilename.c_str());
      return 1;
    } else {
      // Run our queue of passes all at once now, efficiently.
      Passes.run(*M.get());
    }

    // Delete the ostream if it's not a stdout stream
    if (Out != &std::cout) delete Out;

    return 0;
  } catch (const std::string& msg) {
    std::cerr << argv[0] << ": " << msg << "\n";
  } catch (...) {
    std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
  }
  return 1;
}
<|endoftext|>