<commit_before>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/

/*
 * Manipulation of GL extensions.
 *
 * So far we insert GREMEDY extensions, but in the future we could also clamp
 * the GL extensions to core GL versions here.
 */

#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <string>
#include <map>

#include "glproc.hpp"
#include "gltrace.hpp"
#include "os.hpp"
#include "config.hpp"

namespace gltrace {

typedef std::map<std::string, const char *> ExtensionsMap;

// Cache of the translated extensions strings
static ExtensionsMap extensionsMap;

// Additional extensions to be advertised
static const char *
extraExtension_stringsFull[] = {
    "GL_GREMEDY_string_marker",
    "GL_GREMEDY_frame_terminator",
    "GL_ARB_debug_output",
    "GL_AMD_debug_output",
    "GL_KHR_debug",
    "GL_EXT_debug_marker",
    "GL_EXT_debug_label",
    "GL_VMWX_map_buffer_debug",
};

static const char *
extraExtension_stringsES[] = {
    "GL_KHR_debug",
    "GL_EXT_debug_marker",
    "GL_EXT_debug_label",
};

// Description of additional extensions we want to advertise
struct ExtensionsDesc
{
    unsigned numStrings;
    const char **strings;
};

#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))

const struct ExtensionsDesc
extraExtensionsFull = {
    ARRAY_SIZE(extraExtension_stringsFull),
    extraExtension_stringsFull
};

const struct ExtensionsDesc
extraExtensionsES = {
    ARRAY_SIZE(extraExtension_stringsES),
    extraExtension_stringsES
};

const struct ExtensionsDesc *
getExtraExtensions(const Context *ctx)
{
    switch (ctx->profile.api) {
    case glprofile::API_GL:
        return &extraExtensionsFull;
    case glprofile::API_GLES:
        return &extraExtensionsES;
    default:
        assert(0);
        return &extraExtensionsFull;
    }
}

/**
 * Translate the GL extensions string, adding new extensions.
 */
static const char *
overrideExtensionsString(const char *extensions)
{
    const Context *ctx = getContext();
    const ExtensionsDesc *desc = getExtraExtensions(ctx);
    size_t i;

    ExtensionsMap::const_iterator it = extensionsMap.find(extensions);
    if (it != extensionsMap.end()) {
        return it->second;
    }

    size_t extensionsLen = strlen(extensions);

    size_t extraExtensionsLen = 0;
    for (i = 0; i < desc->numStrings; ++i) {
        const char * extraExtension = desc->strings[i];
        size_t extraExtensionLen = strlen(extraExtension);
        extraExtensionsLen += extraExtensionLen + 1;
    }

    // We use malloc memory instead of a std::string because we need to ensure
    // that extensions strings will not move in memory as the extensionsMap is
    // updated.
    size_t newExtensionsLen = extensionsLen + 1 + extraExtensionsLen + 1;
    char *newExtensions = (char *)malloc(newExtensionsLen);
    if (!newExtensions) {
        return extensions;
    }

    if (extensionsLen) {
        memcpy(newExtensions, extensions, extensionsLen);

        // Add space separator if necessary
        if (newExtensions[extensionsLen - 1] != ' ') {
            newExtensions[extensionsLen++] = ' ';
        }
    }

    for (i = 0; i < desc->numStrings; ++i) {
        const char * extraExtension = desc->strings[i];
        size_t extraExtensionLen = strlen(extraExtension);
        memcpy(newExtensions + extensionsLen, extraExtension, extraExtensionLen);
        extensionsLen += extraExtensionLen;
        newExtensions[extensionsLen++] = ' ';
    }
    newExtensions[extensionsLen++] = '\0';
    assert(extensionsLen <= newExtensionsLen);

    extensionsMap[extensions] = newExtensions;

    return newExtensions;
}

const GLubyte *
_glGetString_override(GLenum name)
{
    const configuration *config = getConfig();
    const GLubyte *result;

    // Try getting the override string value first
    result = getConfigString(config, name);
    if (!result) {
        // Ask the real GL library
        result = _glGetString(name);
    }

    if (result) {
        switch (name) {
        case GL_EXTENSIONS:
            result = (const GLubyte *)overrideExtensionsString((const char *)result);
            break;
        default:
            break;
        }
    }

    return result;
}

static void
getInteger(const configuration *config,
           GLenum pname, GLint *params)
{
    // Disable ARB_get_program_binary
    switch (pname) {
    case GL_NUM_PROGRAM_BINARY_FORMATS:
        if (params) {
            if (params[0] > 0) {
                os::log("apitrace: warning: hiding program binary formats (https://github.com/apitrace/apitrace/issues/316)\n");
                params[0] = 0;
            }
        }
        return;
    case GL_PROGRAM_BINARY_FORMATS:
        // params might be NULL here, as we returned 0 for
        // GL_NUM_PROGRAM_BINARY_FORMATS.
        return;
    }

    if (params) {
        *params = getConfigInteger(config, pname);
        if (*params != 0) {
            return;
        }
    }

    // Ask the real GL library
    _glGetIntegerv(pname, params);
}

/**
 * TODO: To be thorough, we should override all glGet*v.
 */
void
_glGetIntegerv_override(GLenum pname, GLint *params)
{
    const configuration *config = getConfig();

    /*
     * It's important to handle params==NULL correctly here, which can and does
     * happen, particularly when pname is GL_COMPRESSED_TEXTURE_FORMATS or
     * GL_PROGRAM_BINARY_FORMATS and the implementation returns 0 for
     * GL_NUM_COMPRESSED_TEXTURE_FORMATS or GL_NUM_PROGRAM_BINARY_FORMATS, as
     * the application ends up calling `params = malloc(0)` or `param = new
     * GLint[0]` which can yield NULL.
     */

    getInteger(config, pname, params);

    if (params) {
        const Context *ctx;
        switch (pname) {
        case GL_NUM_EXTENSIONS:
            ctx = getContext();
            if (ctx->profile.major >= 3) {
                const ExtensionsDesc *desc = getExtraExtensions(ctx);
                *params += desc->numStrings;
            }
            break;
        case GL_MAX_LABEL_LENGTH:
            /* We provide our default implementation of KHR_debug when the
             * driver does not.  So return something sensible here.
             */
            if (params[0] == 0) {
                params[0] = 256;
            }
            break;
        }
    }
}

const GLubyte *
_glGetStringi_override(GLenum name, GLuint index)
{
    const configuration *config = getConfig();
    const Context *ctx = getContext();
    const GLubyte *retVal;

    if (ctx->profile.major >= 3) {
        switch (name) {
        case GL_EXTENSIONS:
            {
                const ExtensionsDesc *desc = getExtraExtensions(ctx);
                GLint numExtensions = 0;
                getInteger(config, GL_NUM_EXTENSIONS, &numExtensions);
                if ((GLuint)numExtensions <= index && index < (GLuint)numExtensions + desc->numStrings) {
                    return (const GLubyte *)desc->strings[index - (GLuint)numExtensions];
                }
            }
            break;
        default:
            break;
        }
    }

    retVal = getConfigStringi(config, name, index);
    if (retVal)
        return retVal;

    return _glGetStringi(name, index);
}

} /* namespace gltrace */

<commit_msg>gltrace: Fix warning for issue 316.<commit_after>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/

/*
 * Manipulation of GL extensions.
 *
 * So far we insert GREMEDY extensions, but in the future we could also clamp
 * the GL extensions to core GL versions here.
 */

#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <string>
#include <map>

#include "glproc.hpp"
#include "gltrace.hpp"
#include "os.hpp"
#include "config.hpp"

namespace gltrace {

typedef std::map<std::string, const char *> ExtensionsMap;

// Cache of the translated extensions strings
static ExtensionsMap extensionsMap;

// Additional extensions to be advertised
static const char *
extraExtension_stringsFull[] = {
    "GL_GREMEDY_string_marker",
    "GL_GREMEDY_frame_terminator",
    "GL_ARB_debug_output",
    "GL_AMD_debug_output",
    "GL_KHR_debug",
    "GL_EXT_debug_marker",
    "GL_EXT_debug_label",
    "GL_VMWX_map_buffer_debug",
};

static const char *
extraExtension_stringsES[] = {
    "GL_KHR_debug",
    "GL_EXT_debug_marker",
    "GL_EXT_debug_label",
};

// Description of additional extensions we want to advertise
struct ExtensionsDesc
{
    unsigned numStrings;
    const char **strings;
};

#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))

const struct ExtensionsDesc
extraExtensionsFull = {
    ARRAY_SIZE(extraExtension_stringsFull),
    extraExtension_stringsFull
};

const struct ExtensionsDesc
extraExtensionsES = {
    ARRAY_SIZE(extraExtension_stringsES),
    extraExtension_stringsES
};

const struct ExtensionsDesc *
getExtraExtensions(const Context *ctx)
{
    switch (ctx->profile.api) {
    case glprofile::API_GL:
        return &extraExtensionsFull;
    case glprofile::API_GLES:
        return &extraExtensionsES;
    default:
        assert(0);
        return &extraExtensionsFull;
    }
}

/**
 * Translate the GL extensions string, adding new extensions.
 */
static const char *
overrideExtensionsString(const char *extensions)
{
    const Context *ctx = getContext();
    const ExtensionsDesc *desc = getExtraExtensions(ctx);
    size_t i;

    ExtensionsMap::const_iterator it = extensionsMap.find(extensions);
    if (it != extensionsMap.end()) {
        return it->second;
    }

    size_t extensionsLen = strlen(extensions);

    size_t extraExtensionsLen = 0;
    for (i = 0; i < desc->numStrings; ++i) {
        const char * extraExtension = desc->strings[i];
        size_t extraExtensionLen = strlen(extraExtension);
        extraExtensionsLen += extraExtensionLen + 1;
    }

    // We use malloc memory instead of a std::string because we need to ensure
    // that extensions strings will not move in memory as the extensionsMap is
    // updated.
    size_t newExtensionsLen = extensionsLen + 1 + extraExtensionsLen + 1;
    char *newExtensions = (char *)malloc(newExtensionsLen);
    if (!newExtensions) {
        return extensions;
    }

    if (extensionsLen) {
        memcpy(newExtensions, extensions, extensionsLen);

        // Add space separator if necessary
        if (newExtensions[extensionsLen - 1] != ' ') {
            newExtensions[extensionsLen++] = ' ';
        }
    }

    for (i = 0; i < desc->numStrings; ++i) {
        const char * extraExtension = desc->strings[i];
        size_t extraExtensionLen = strlen(extraExtension);
        memcpy(newExtensions + extensionsLen, extraExtension, extraExtensionLen);
        extensionsLen += extraExtensionLen;
        newExtensions[extensionsLen++] = ' ';
    }
    newExtensions[extensionsLen++] = '\0';
    assert(extensionsLen <= newExtensionsLen);

    extensionsMap[extensions] = newExtensions;

    return newExtensions;
}

const GLubyte *
_glGetString_override(GLenum name)
{
    const configuration *config = getConfig();
    const GLubyte *result;

    // Try getting the override string value first
    result = getConfigString(config, name);
    if (!result) {
        // Ask the real GL library
        result = _glGetString(name);
    }

    if (result) {
        switch (name) {
        case GL_EXTENSIONS:
            result = (const GLubyte *)overrideExtensionsString((const char *)result);
            break;
        default:
            break;
        }
    }

    return result;
}

static void
getInteger(const configuration *config,
           GLenum pname, GLint *params)
{
    // Disable ARB_get_program_binary
    switch (pname) {
    case GL_NUM_PROGRAM_BINARY_FORMATS:
        if (params) {
            GLint numProgramBinaryFormats = 0;
            _glGetIntegerv(pname, &numProgramBinaryFormats);
            if (numProgramBinaryFormats > 0) {
                os::log("apitrace: warning: hiding program binary formats (https://github.com/apitrace/apitrace/issues/316)\n");
            }
            params[0] = 0;
        }
        return;
    case GL_PROGRAM_BINARY_FORMATS:
        // params might be NULL here, as we returned 0 for
        // GL_NUM_PROGRAM_BINARY_FORMATS.
        return;
    }

    if (params) {
        *params = getConfigInteger(config, pname);
        if (*params != 0) {
            return;
        }
    }

    // Ask the real GL library
    _glGetIntegerv(pname, params);
}

/**
 * TODO: To be thorough, we should override all glGet*v.
 */
void
_glGetIntegerv_override(GLenum pname, GLint *params)
{
    const configuration *config = getConfig();

    /*
     * It's important to handle params==NULL correctly here, which can and does
     * happen, particularly when pname is GL_COMPRESSED_TEXTURE_FORMATS or
     * GL_PROGRAM_BINARY_FORMATS and the implementation returns 0 for
     * GL_NUM_COMPRESSED_TEXTURE_FORMATS or GL_NUM_PROGRAM_BINARY_FORMATS, as
     * the application ends up calling `params = malloc(0)` or `param = new
     * GLint[0]` which can yield NULL.
     */

    getInteger(config, pname, params);

    if (params) {
        const Context *ctx;
        switch (pname) {
        case GL_NUM_EXTENSIONS:
            ctx = getContext();
            if (ctx->profile.major >= 3) {
                const ExtensionsDesc *desc = getExtraExtensions(ctx);
                *params += desc->numStrings;
            }
            break;
        case GL_MAX_LABEL_LENGTH:
            /* We provide our default implementation of KHR_debug when the
             * driver does not.  So return something sensible here.
             */
            if (params[0] == 0) {
                params[0] = 256;
            }
            break;
        }
    }
}

const GLubyte *
_glGetStringi_override(GLenum name, GLuint index)
{
    const configuration *config = getConfig();
    const Context *ctx = getContext();
    const GLubyte *retVal;

    if (ctx->profile.major >= 3) {
        switch (name) {
        case GL_EXTENSIONS:
            {
                const ExtensionsDesc *desc = getExtraExtensions(ctx);
                GLint numExtensions = 0;
                getInteger(config, GL_NUM_EXTENSIONS, &numExtensions);
                if ((GLuint)numExtensions <= index && index < (GLuint)numExtensions + desc->numStrings) {
                    return (const GLubyte *)desc->strings[index - (GLuint)numExtensions];
                }
            }
            break;
        default:
            break;
        }
    }

    retVal = getConfigStringi(config, name, index);
    if (retVal)
        return retVal;

    return _glGetStringi(name, index);
}

} /* namespace gltrace */

<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
//  File: OutputVtk.cpp
//
//  For more information, please see: http://www.nektar.info/
//
//  The MIT License
//
//  Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
//  Department of Aeronautics, Imperial College London (UK), and Scientific
//  Computing and Imaging Institute, University of Utah (USA).
//
//  License for the specific language governing rights and limitations under
//  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.
//
//  Description: DAT file format output.
//
////////////////////////////////////////////////////////////////////////////////

#include <set>
#include <string>
using namespace std;

#include "OutputTecplot.h"

namespace Nektar
{
    namespace Utilities
    {
        ModuleKey OutputTecplot::m_className =
            GetModuleFactory().RegisterCreatorFunction(
                ModuleKey(eOutputModule, "dat"), OutputTecplot::create,
                "Writes a Tecplot file.");

        OutputTecplot::OutputTecplot(FieldSharedPtr f) : OutputModule(f)
        {
            m_requireEquiSpaced = true;
        }

        OutputTecplot::~OutputTecplot()
        {
        }

        void OutputTecplot::Process(po::variables_map &vm)
        {
            if (m_f->m_verbose)
            {
                cout << "OutputTecplot: Writing file..." << endl;
            }

            int expdim  = m_f->m_graph->GetMeshDimension();

            // Extract the output filename and extension
            string filename = m_config["outfile"].as<string>();

            // amend for parallel output if required
            if(m_f->m_session->GetComm()->GetSize() != 1)
            {
                int    dot  = filename.find_last_of('.');
                string ext = filename.substr(dot,filename.length()-dot);
                string procId = "_P" + boost::lexical_cast<std::string>(m_f->m_session->GetComm()->GetRank());
                string start = filename.substr(0,dot);
                filename = start + procId + ext;
            }
            // Write solution.
            ofstream outfile(filename.c_str());

            std::string var = m_f->m_fielddef[0]->m_fields[0];

            for (int j = 1; j < m_f->m_fielddef[0]->m_fields.size(); ++j)
            {
                var = var + ", " + m_f->m_fielddef[0]->m_fields[j];
            }

            if (expdim == 3)
            {
                WriteTecplotHeader(outfile,var);
                WriteTecplotZone(outfile);
                for(int j = 0; j < m_f->m_exp.size(); ++j)
                {
                    WriteTecplotField(j,outfile);
                }
                WriteTecplotConnectivity(outfile);
            }
            else
            {
                WriteTecplotHeader(outfile,var);
                for (int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
                {
                    WriteTecplotZone(outfile,i);
                    for (int j = 0; j < m_f->m_fielddef[0]->m_fields.size(); ++j)
                    {
                        WriteTecplotField(j,outfile,i);
                    }
                }
            }

            cout << "Written file: " << filename << endl;
            //  Put in a block ot amke sure all outputs have been completed
            m_f->m_session->GetComm()->Block();
        }

        /**
         * Write Tecplot Files Header
         * @param   outfile Output file name.
         * @param   var                 variables names
         */
        void OutputTecplot::WriteTecplotHeader(std::ofstream &outfile,
                                               std::string var)
        {

            int coordim  = m_f->m_exp[0]->GetExp(0)->GetCoordim();
            outfile << "Variables = x";

            if(coordim == 2)
            {
                outfile << ", y";
            }
            else if (coordim == 3)
            {
                outfile << ", y, z";
            }
            outfile << ", "<< var << std::endl << std::endl;
        }

        /**
         * Write Tecplot Files Zone
         * @param   outfile    Output file name.
         * @param   expansion  Expansion that is considered
         */
        void OutputTecplot::WriteTecplotZone(std::ofstream &outfile,
                                             int expansion)
        {
            if(expansion == -1) //write as full block zone
            {
                int i,j;
                int coordim   = m_f->m_exp[0]->GetCoordim(0);
                int totpoints = m_f->m_exp[0]->GetTotPoints();

                Array<OneD,NekDouble> coords[3];

                coords[0] = Array<OneD,NekDouble>(totpoints);
                coords[1] = Array<OneD,NekDouble>(totpoints);
                coords[2] = Array<OneD,NekDouble>(totpoints);

                m_f->m_exp[0]->GetCoords(coords[0],coords[1],coords[2]);

                outfile << "Zone, N=" << totpoints << ", E="<<
                    GetNumTecplotBlocks() << ", F=FEBlock" ;

                switch(m_f->m_exp[0]->GetExp(0)->GetNumBases())
                {
                case 1:
                    ASSERTL0(false,"Not set up for this type of output");
                    break;
                case 2:
                    outfile << ", ET=QUADRILATERAL" << std::endl;
                    break;
                case 3:
                    outfile << ", ET=BRICK" << std::endl;
                    break;
                }

                // write out coordinates in block format
                for(j = 0; j < coordim; ++j)
                {
                    for(i = 0; i < totpoints; ++i)
                    {
                        outfile << coords[j][i] << " ";
                        if((!(i % 1000))&&i)
                        {
                            outfile << std::endl;
                        }
                    }
                    outfile << std::endl;
                }

            }
            else
            {
                m_f->m_exp[0]->GetExp(expansion)->WriteTecplotZone(outfile);
            }
        }

        int OutputTecplot::GetNumTecplotBlocks(void)
        {
            int returnval = 0;

            if(m_f->m_exp[0]->GetExp(0)->GetNumBases() == 2)
            {
                for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
                {
                    returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1)*
                        (m_f->m_exp[0]->GetExp(i)->GetNumPoints(1)-1);
                }
            }
            else
            {
                for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
                {
                    returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1)*
                        (m_f->m_exp[0]->GetExp(i)->GetNumPoints(1)-1)*
                        (m_f->m_exp[0]->GetExp(i)->GetNumPoints(2)-1);
                }
            }

            return returnval;
        }

        /**
         * Write Tecplot Files Field
         * @param   outfile    Output file name.
         * @param   expansion  Expansion that is considered
         */
        void OutputTecplot::WriteTecplotField(const int field,
                                              std::ofstream &outfile,
                                              int expansion)
        {

            if(expansion == -1)
            {
                int totpoints = m_f->m_exp[0]->GetTotPoints();

                if(m_f->m_exp[field]->GetPhysState() == false)
                {
                    m_f->m_exp[field]->BwdTrans(m_f->m_exp[field]->GetCoeffs(),
                                                m_f->m_exp[field]->UpdatePhys());
                }

                for(int i = 0; i < totpoints; ++i)
                {
                    outfile << m_f->m_exp[field]->GetPhys()[i] << " ";
                    if((!(i % 1000))&&i)
                    {
                        outfile << std::endl;
                    }
                }
                outfile << std::endl;
            }
            else
            {
                m_f->m_exp[field]->GetExp(expansion)->SetPhys(
                                  m_f->m_exp[field]->GetPhys()+
                                  m_f->m_exp[field]->GetPhys_Offset(expansion));
                m_f->m_exp[field]->GetExp(expansion)->WriteTecplotField(outfile);
            }
        }

        void  OutputTecplot::WriteTecplotConnectivity(std::ofstream &outfile)
        {
            int i,j,k,l;
            int nbase = m_f->m_exp[0]->GetExp(0)->GetNumBases();
            int cnt = 0;

            for(i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
            {
                if(nbase == 2)
                {
                    int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
                    int np1 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(1);

                    for(j = 1; j < np1; ++j)
                    {
                        for(k = 1; k < np0; ++k)
                        {
                            outfile << cnt + (j-1)*np0 + k  << " ";
                            outfile << cnt + (j-1)*np0 + k +1 << " ";
                            outfile << cnt + j*np0 + k +1 << " ";
                            outfile << cnt + j*np0 + k    << endl;
                        }
                    }

                    cnt += np0*np1;
                }
                else if(nbase == 3)
                {
                    int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
                    int np1 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(1);
                    int np2 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(2);

                    for(j = 1; j < np2; ++j)
                    {
                        for(k = 1; k < np1; ++k)
                        {
                            for(l = 1; l < np0; ++l)
                            {
                                outfile << cnt + (j-1)*np0*np1 + (k-1)*np0 + l  << " ";
                                outfile << cnt + (j-1)*np0*np1 + (k-1)*np0 + l +1 << " ";
                                outfile << cnt + (j-1)*np0*np1 +  k*np0 + l +1 << " ";
                                outfile << cnt + (j-1)*np0*np1 +  k*np0 + l  << " ";

                                outfile << cnt + j*np0*np1 + (k-1)*np0 + l  << " ";
                                outfile << cnt + j*np0*np1 + (k-1)*np0 + l +1 << " ";
                                outfile << cnt + j*np0*np1 +  k*np0 + l +1 << " ";
                                outfile << cnt + j*np0*np1 +  k*np0 + l  << endl;
                            }
                        }
                    }
                    cnt += np0*np1*np2;
                }
                else
                {
                    ASSERTL0(false,"Not set up for this dimension");
                }

            }
        }

    }
}

<commit_msg>Updated for current master<commit_after>////////////////////////////////////////////////////////////////////////////////
//
//  File: OutputVtk.cpp
//
//  For more information, please see: http://www.nektar.info/
//
//  The MIT License
//
//  Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
//  Department of Aeronautics, Imperial College London (UK), and Scientific
//  Computing and Imaging Institute, University of Utah (USA).
//
//  License for the specific language governing rights and limitations under
//  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.
//
//  Description: DAT file format output.
//
////////////////////////////////////////////////////////////////////////////////

#include <set>
#include <string>
using namespace std;

#include "OutputTecplot.h"

namespace Nektar
{
    namespace Utilities
    {
        ModuleKey OutputTecplot::m_className =
            GetModuleFactory().RegisterCreatorFunction(
                ModuleKey(eOutputModule, "dat"), OutputTecplot::create,
                "Writes a Tecplot file.");

        OutputTecplot::OutputTecplot(FieldSharedPtr f) : OutputModule(f)
        {
            m_requireEquiSpaced = true;
        }

        OutputTecplot::~OutputTecplot()
        {
        }

        void OutputTecplot::Process(po::variables_map &vm)
        {
            if (m_f->m_verbose)
            {
                cout << "OutputTecplot: Writing file..." << endl;
            }

            int expdim  = m_f->m_graph->GetMeshDimension();

            // Extract the output filename and extension
            string filename = m_config["outfile"].as<string>();

            // amend for parallel output if required
            if(m_f->m_session->GetComm()->GetSize() != 1)
            {
                int    dot  = filename.find_last_of('.');
                string ext = filename.substr(dot,filename.length()-dot);
                string procId = "_P" + boost::lexical_cast<std::string>(m_f->m_session->GetComm()->GetRank());
                string start = filename.substr(0,dot);
                filename = start + procId + ext;
            }
            // Write solution.
            ofstream outfile(filename.c_str());

            std::string var = m_f->m_fielddef[0]->m_fields[0];

            for (int j = 1; j < m_f->m_fielddef[0]->m_fields.size(); ++j)
            {
                var = var + ", " + m_f->m_fielddef[0]->m_fields[j];
            }

            if (expdim == 3)
            {
                WriteTecplotHeader(outfile,var);
                WriteTecplotZone(outfile);
                for(int j = 0; j < m_f->m_exp.size(); ++j)
                {
                    WriteTecplotField(j,outfile);
                }
                WriteTecplotConnectivity(outfile);
            }
            else
            {
                WriteTecplotHeader(outfile,var);
                for (int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
                {
                    WriteTecplotZone(outfile,i);
                    for (int j = 0; j < m_f->m_fielddef[0]->m_fields.size(); ++j)
                    {
                        WriteTecplotField(j,outfile,i);
                    }
                }
            }

            cout << "Written file: " << filename << endl;
            //  Put in a block ot amke sure all outputs have been completed
            m_f->m_session->GetComm()->Block();
        }

        /**
         * Write Tecplot Files Header
         * @param   outfile Output file name.
         * @param   var                 variables names
         */
        void OutputTecplot::WriteTecplotHeader(std::ofstream &outfile,
                                               std::string var)
        {

            int coordim  = m_f->m_exp[0]->GetExp(0)->GetCoordim();
            outfile << "Variables = x";

            if(coordim == 2)
            {
                outfile << ", y";
            }
            else if (coordim == 3)
            {
                outfile << ", y, z";
            }
            outfile << ", "<< var << std::endl << std::endl;
        }

        /**
         * Write Tecplot Files Zone
         * @param   outfile    Output file name.
         * @param   expansion  Expansion that is considered
         */
        void OutputTecplot::WriteTecplotZone(std::ofstream &outfile,
                                             int expansion)
        {
            if(expansion == -1) //write as full block zone
            {
                int i,j;
                int coordim   = m_f->m_exp[0]->GetCoordim(0);
                int totpoints = m_f->m_exp[0]->GetTotPoints();

                Array<OneD,NekDouble> coords[3];

                coords[0] = Array<OneD,NekDouble>(totpoints);
                coords[1] = Array<OneD,NekDouble>(totpoints);
                coords[2] = Array<OneD,NekDouble>(totpoints);

                m_f->m_exp[0]->GetCoords(coords[0],coords[1],coords[2]);

                outfile << "Zone, N=" << totpoints << ", E="<<
                    GetNumTecplotBlocks() << ", F=FEBlock" ;

                switch(m_f->m_exp[0]->GetExp(0)->GetNumBases())
                {
                case 1:
                    ASSERTL0(false,"Not set up for this type of output");
                    break;
                case 2:
                    outfile << ", ET=QUADRILATERAL" << std::endl;
                    break;
                case 3:
                    outfile << ", ET=BRICK" << std::endl;
                    break;
                }

                // write out coordinates in block format
                for(j = 0; j < coordim; ++j)
                {
                    for(i = 0; i < totpoints; ++i)
                    {
                        outfile << coords[j][i] << " ";
                        if((!(i % 1000))&&i)
                        {
                            outfile << std::endl;
                        }
                    }
                    outfile << std::endl;
                }

            }
            else
            {
                m_f->m_exp[0]->WriteTecplotZone(outfile,expansion);
            }
        }

        int OutputTecplot::GetNumTecplotBlocks(void)
        {
            int returnval = 0;

            if(m_f->m_exp[0]->GetExp(0)->GetNumBases() == 2)
            {
                for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
                {
                    returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1)*
                        (m_f->m_exp[0]->GetExp(i)->GetNumPoints(1)-1);
                }
            }
            else
            {
                for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
                {
                    returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1)*
                        (m_f->m_exp[0]->GetExp(i)->GetNumPoints(1)-1)*
                        (m_f->m_exp[0]->GetExp(i)->GetNumPoints(2)-1);
                }
            }

            return returnval;
        }

        /**
         * Write Tecplot Files Field
         * @param   outfile    Output file name.
         * @param   expansion  Expansion that is considered
         */
        void OutputTecplot::WriteTecplotField(const int field,
                                              std::ofstream &outfile,
                                              int expansion)
        {

            if(expansion == -1)
            {
                int totpoints = m_f->m_exp[0]->GetTotPoints();

                if(m_f->m_exp[field]->GetPhysState() == false)
                {
                    m_f->m_exp[field]->BwdTrans(m_f->m_exp[field]->GetCoeffs(),
                                                m_f->m_exp[field]->UpdatePhys());
                }

                for(int i = 0; i < totpoints; ++i)
                {
                    outfile << m_f->m_exp[field]->GetPhys()[i] << " ";
                    if((!(i % 1000))&&i)
                    {
                        outfile << std::endl;
                    }
                }
                outfile << std::endl;
            }
            else
            {
                m_f->m_exp[field]->WriteTecplotField(outfile,expansion);
            }
        }

        void  OutputTecplot::WriteTecplotConnectivity(std::ofstream &outfile)
        {
            int i,j,k,l;
            int nbase = m_f->m_exp[0]->GetExp(0)->GetNumBases();
            int cnt = 0;

            for(i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
            {
                if(nbase == 2)
                {
                    int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
                    int np1 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(1);

                    for(j = 1; j < np1; ++j)
                    {
                        for(k = 1; k < np0; ++k)
                        {
                            outfile << cnt + (j-1)*np0 + k  << " ";
                            outfile << cnt + (j-1)*np0 + k +1 << " ";
                            outfile << cnt + j*np0 + k +1 << " ";
                            outfile << cnt + j*np0 + k    << endl;
                        }
                    }

                    cnt += np0*np1;
                }
                else if(nbase == 3)
                {
                    int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
                    int np1 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(1);
                    int np2 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(2);

                    for(j = 1; j < np2; ++j)
                    {
                        for(k = 1; k < np1; ++k)
                        {
                            for(l = 1; l < np0; ++l)
                            {
                                outfile << cnt + (j-1)*np0*np1 + (k-1)*np0 + l  << " ";
                                outfile << cnt + (j-1)*np0*np1 + (k-1)*np0 + l +1 << " ";
                                outfile << cnt + (j-1)*np0*np1 +  k*np0 + l +1 << " ";
                                outfile << cnt + (j-1)*np0*np1 +  k*np0 + l  << " ";

                                outfile << cnt + j*np0*np1 + (k-1)*np0 + l  << " ";
                                outfile << cnt + j*np0*np1 + (k-1)*np0 + l +1 << " ";
                                outfile << cnt + j*np0*np1 +  k*np0 + l +1 << " ";
                                outfile << cnt + j*np0*np1 +  k*np0 + l  << endl;
                            }
                        }
                    }
                    cnt += np0*np1*np2;
                }
                else
                {
                    ASSERTL0(false,"Not set up for this dimension");
                }

            }
        }

    }
}

<|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.

// When possible, we implement allocator functions on top of the basic
// low-level functions malloc() and free().  This way, including a new
// allocator is as simple as providing just a small interface.
//
// As such, this file should not contain any allocator-specific code.

// Implement a C++ style allocation, which always calls the new_handler
// on failure.
inline void* generic_cpp_alloc(size_t size, bool nothrow) {
  void* ptr;
  for (;;) {
    ptr = malloc(size);
    if (ptr)
      return ptr;
    if (!call_new_handler(nothrow))
      break;
  }
  return ptr;
}

extern "C++" {

void* __cdecl operator new(size_t size) {
  return generic_cpp_alloc(size, false);
}

void operator delete(void* p) __THROW {
  free(p);
}

void* operator new[](size_t size) {
  return generic_cpp_alloc(size, false);
}

void operator delete[](void* p) __THROW {
  free(p);
}

void* operator new(size_t size, const std::nothrow_t& nt) __THROW {
  return generic_cpp_alloc(size, true);
}

void* operator new[](size_t size, const std::nothrow_t& nt) __THROW {
  return generic_cpp_alloc(size, true);
}

// This function behaves similarly to MSVC's _set_new_mode.
// If flag is 0 (default), calls to malloc will behave normally.
// If flag is 1, calls to malloc will behave like calls to new,
// and the std_new_handler will be invoked on failure.
// Returns the previous mode.
int _set_new_mode(int flag) __THROW {
  int old_mode = new_mode;
  new_mode = flag;
  return old_mode;
}

}  // extern "C++"

extern "C" {

void* calloc(size_t n, size_t elem_size) __THROW {
  // Overflow check
  const size_t size = n * elem_size;
  if (elem_size != 0 && size / elem_size != n) return NULL;

  void* result = malloc(size);
  if (result != NULL) {
    memset(result, 0, size);
  }
  return result;
}

void cfree(void* p) __THROW {
  free(p);
}

#ifdef WIN32

void* _recalloc(void* p, size_t n, size_t elem_size) {
  if (!p)
    return calloc(n, elem_size);

  // This API is a bit odd.
  // Note: recalloc only guarantees zeroed memory when p is NULL.
  //   Generally, calls to malloc() have padding.  So a request
  //   to malloc N bytes actually malloc's N+x bytes.  Later, if
  //   that buffer is passed to recalloc, we don't know what N
  //   was anymore.  We only know what N+x is.  As such, there is
  //   no way to know what to zero out.
  const size_t size = n * elem_size;
  if (elem_size != 0 && size / elem_size != n) return NULL;
  return realloc(p, size);
}

void* _calloc_impl(size_t n, size_t size) {
  return calloc(n, size);
}

#ifndef NDEBUG
#undef malloc
#undef free
#undef calloc

static int error_handler(int reportType) {
  switch (reportType) {
    case 0:  // _CRT_WARN
      __debugbreak();
      return 0;

    case 1:  // _CRT_ERROR
      __debugbreak();
      return 0;

    case 2:  // _CRT_ASSERT
      __debugbreak();
      return 0;
  }
  char* p = NULL;
  *p = '\0';
  return 0;
}

int _CrtDbgReport(int reportType,
                  const char*,
                  int, const char*,
                  const char*,
                  ...) {
  return error_handler(reportType);
}

int _CrtDbgReportW(int reportType,
                   const wchar_t*,
                   int, const wchar_t*,
                   const wchar_t*,
                   ...) {
  return error_handler(reportType);
}

int _CrtSetReportMode(int, int) {
  return 0;
}

void* _malloc_dbg(size_t size, int , const char*, int) {
  return malloc(size);
}

void _free_dbg(void* ptr, int) {
  free(ptr);
}

void* _calloc_dbg(size_t n, size_t size, int, const char*, int) {
  return calloc(n, size);
}
#endif  // NDEBUG

#endif  // WIN32

}  // extern C

<commit_msg>Add realloc_dbg to satisfy the libcpmtd which is provided with Visual Studio 2012. Review URL: https://codereview.chromium.org/11361071<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.

// When possible, we implement allocator functions on top of the basic
// low-level functions malloc() and free().  This way, including a new
// allocator is as simple as providing just a small interface.
//
// As such, this file should not contain any allocator-specific code.

// Implement a C++ style allocation, which always calls the new_handler
// on failure.
inline void* generic_cpp_alloc(size_t size, bool nothrow) {
  void* ptr;
  for (;;) {
    ptr = malloc(size);
    if (ptr)
      return ptr;
    if (!call_new_handler(nothrow))
      break;
  }
  return ptr;
}

extern "C++" {

void* __cdecl operator new(size_t size) {
  return generic_cpp_alloc(size, false);
}

void operator delete(void* p) __THROW {
  free(p);
}

void* operator new[](size_t size) {
  return generic_cpp_alloc(size, false);
}

void operator delete[](void* p) __THROW {
  free(p);
}

void* operator new(size_t size, const std::nothrow_t& nt) __THROW {
  return generic_cpp_alloc(size, true);
}

void* operator new[](size_t size, const std::nothrow_t& nt) __THROW {
  return generic_cpp_alloc(size, true);
}

// This function behaves similarly to MSVC's _set_new_mode.
// If flag is 0 (default), calls to malloc will behave normally.
// If flag is 1, calls to malloc will behave like calls to new,
// and the std_new_handler will be invoked on failure.
// Returns the previous mode.
int _set_new_mode(int flag) __THROW {
  int old_mode = new_mode;
  new_mode = flag;
  return old_mode;
}

}  // extern "C++"

extern "C" {

void* calloc(size_t n, size_t elem_size) __THROW {
  // Overflow check
  const size_t size = n * elem_size;
  if (elem_size != 0 && size / elem_size != n) return NULL;

  void* result = malloc(size);
  if (result != NULL) {
    memset(result, 0, size);
  }
  return result;
}

void cfree(void* p) __THROW {
  free(p);
}

#ifdef WIN32

void* _recalloc(void* p, size_t n, size_t elem_size) {
  if (!p)
    return calloc(n, elem_size);

  // This API is a bit odd.
  // Note: recalloc only guarantees zeroed memory when p is NULL.
  //   Generally, calls to malloc() have padding.  So a request
  //   to malloc N bytes actually malloc's N+x bytes.  Later, if
  //   that buffer is passed to recalloc, we don't know what N
  //   was anymore.  We only know what N+x is.  As such, there is
  //   no way to know what to zero out.
  const size_t size = n * elem_size;
  if (elem_size != 0 && size / elem_size != n) return NULL;
  return realloc(p, size);
}

void* _calloc_impl(size_t n, size_t size) {
  return calloc(n, size);
}

#ifndef NDEBUG
#undef malloc
#undef free
#undef calloc

static int error_handler(int reportType) {
  switch (reportType) {
    case 0:  // _CRT_WARN
      __debugbreak();
      return 0;

    case 1:  // _CRT_ERROR
      __debugbreak();
      return 0;

    case 2:  // _CRT_ASSERT
      __debugbreak();
      return 0;
  }
  char* p = NULL;
  *p = '\0';
  return 0;
}

int _CrtDbgReport(int reportType,
                  const char*,
                  int, const char*,
                  const char*,
                  ...) {
  return error_handler(reportType);
}

int _CrtDbgReportW(int reportType,
                   const wchar_t*,
                   int, const wchar_t*,
                   const wchar_t*,
                   ...) {
  return error_handler(reportType);
}

int _CrtSetReportMode(int, int) {
  return 0;
}

void* _malloc_dbg(size_t size, int , const char*, int) {
  return malloc(size);
}

void* _realloc_dbg(void* ptr, size_t size, int, const char*, int) {
  return realloc(ptr, size);
}

void _free_dbg(void* ptr, int) {
  free(ptr);
}

void* _calloc_dbg(size_t n, size_t size, int, const char*, int) {
  return calloc(n, size);
}
#endif  // NDEBUG

#endif  // WIN32

}  // extern C

<|endoftext|>


<commit_before>#include <cmath>
#include <iostream>

using namespace std;

inline void use_io_iptimizations()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
}

int main()
{
    use_io_iptimizations();

    unsigned int theatre_square_width;
    unsigned int theatre_square_height;
    unsigned int flagstone_size;

    cin >> theatre_square_width >> theatre_square_height >> flagstone_size;

    cout << static_cast<long long>(
                (ceil(theatre_square_width  /
                      static_cast<double>(flagstone_size)) *
                 ceil(theatre_square_height /
                      static_cast<double>(flagstone_size)))
            );

    return 0;
}
<commit_msg>codeforce; avoid using ceil when looking for integer division<commit_after>#include <iostream>

using namespace std;

inline void use_io_iptimizations()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
}

int main()
{
    use_io_iptimizations();

    unsigned long long theatre_square_width;
    unsigned long long theatre_square_height;
    unsigned long long flagstone_size;

    cin >> theatre_square_width >> theatre_square_height >> flagstone_size;

    unsigned long long horizontal {
        (theatre_square_width + flagstone_size - 1) / flagstone_size
    };

    unsigned long long vertical {
        (theatre_square_height + flagstone_size - 1) / flagstone_size
    };

    cout << horizontal * vertical << '\n';

    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: typemanager.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2004-03-30 16:52:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _RTL_ALLOC_H_
#include    <rtl/alloc.h>
#endif

#ifndef _CODEMAKER_TYPEMANAGER_HXX_
#include    <codemaker/typemanager.hxx>
#endif

#include "registry/reader.hxx"
#include "registry/version.h"

using namespace rtl;

TypeManager::TypeManager()
{
    m_pImpl = new TypeManagerImpl();
    acquire();
}

TypeManager::~TypeManager()
{
    release();
}

sal_Int32 TypeManager::acquire()
{
    return osl_incrementInterlockedCount(&m_pImpl->m_refCount);
}

sal_Int32 TypeManager::release()
{
    sal_Int32 refCount = 0;
    if (0 == (refCount = osl_decrementInterlockedCount(&m_pImpl->m_refCount)) )
    {
        delete m_pImpl;
    }
    return refCount;;
}

sal_Bool TypeManager::isBaseType(const ::rtl::OString& name)
{
    if ( name.equals(OString("short")) )
        return sal_True;
    if ( name.equals(OString("unsigned short")) )
        return sal_True;
    if ( name.equals(OString("long")) )
        return sal_True;
    if ( name.equals(OString("unsigned long")) )
        return sal_True;
    if ( name.equals(OString("hyper")) )
        return sal_True;
    if ( name.equals(OString("unsigned hyper")) )
        return sal_True;
    if ( name.equals(OString("string")) )
        return sal_True;
    if ( name.equals(OString("boolean")) )
        return sal_True;
    if ( name.equals(OString("char")) )
        return sal_True;
    if ( name.equals(OString("byte")) )
        return sal_True;
    if ( name.equals(OString("any")) )
        return sal_True;
    if ( name.equals(OString("type")) )
        return sal_True;
    if ( name.equals(OString("float")) )
        return sal_True;
    if ( name.equals(OString("double")) )
        return sal_True;
    if ( name.equals(OString("void")) )
        return sal_True;

    return sal_False;
}

RegistryTypeManager::RegistryTypeManager()
{
    m_pImpl = new RegistryTypeManagerImpl();
    acquire();
}

RegistryTypeManager::~RegistryTypeManager()
{
    release();
}

void RegistryTypeManager::acquire()
{
    TypeManager::acquire();
}

void RegistryTypeManager::release()
{
    if (0 == TypeManager::release())
    {
        freeRegistries();

        delete m_pImpl;
    }
}

sal_Bool RegistryTypeManager::init(
    const StringVector& regFiles,
    StringVector const & extraFiles )
{
    if (regFiles.empty())
        return sal_False;

    StringVector::const_iterator iter = regFiles.begin();

    RegistryLoader loader;
    Registry tmpReg(loader);
    while (iter != regFiles.end())
    {
        if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY))
            m_pImpl->m_registries.push_back(new Registry(tmpReg));
        else
        {
            freeRegistries();
            return sal_False;
        }
        ++iter;
    }
    iter = extraFiles.begin();
    while (iter != extraFiles.end())
    {
        if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY))
            m_pImpl->m_extra_registries.push_back(new Registry(tmpReg));
        else
        {
            freeRegistries();
            return sal_False;
        }
        ++iter;
    }

    return sal_True;
}

typereg::Reader RegistryTypeManager::getTypeReader(
    const OString& name, sal_Bool * pIsExtraType )
{
    typereg::Reader reader;
    RegistryKey key(searchTypeKey(name, pIsExtraType));

    if (key.isValid())
    {
        RegValueType    valueType;
        sal_uInt32      valueSize;

        if (!key.getValueInfo(OUString(), &valueType, &valueSize))
        {
            sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
            if (!key.getValue(OUString(), pBuffer))
            {
                reader = typereg::Reader(
                    pBuffer, valueSize, true, TYPEREG_VERSION_1);
            }
            rtl_freeMemory(pBuffer);
        }
    }
    return reader;
}

RTTypeClass RegistryTypeManager::getTypeClass(const OString& name)
{
    if (m_pImpl->m_t2TypeClass.count(name) > 0)
    {
        return m_pImpl->m_t2TypeClass[name];
    } else
    {
        RegistryKey key(searchTypeKey(name));

        if (key.isValid())
        {
            RegValueType    valueType;
            sal_uInt32      valueSize;

            if (!key.getValueInfo(OUString(), &valueType, &valueSize))
            {
                sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
                if (!key.getValue(OUString(), pBuffer))
                {
                    typereg::Reader reader(
                        pBuffer, valueSize, false, TYPEREG_VERSION_1);

                    RTTypeClass ret = reader.getTypeClass();

                    rtl_freeMemory(pBuffer);

                    m_pImpl->m_t2TypeClass[name] = ret;
                    return ret;
                }
                rtl_freeMemory(pBuffer);
            }
        }
    }

    return RT_TYPE_INVALID;
}

void RegistryTypeManager::setBase(const OString& base)
{
    m_pImpl->m_base = base;

    if (base.lastIndexOf('/') != (base.getLength() - 1))
    {
        m_pImpl->m_base += "/";
    }
}

void RegistryTypeManager::freeRegistries()
{
    RegistryList::const_iterator iter = m_pImpl->m_registries.begin();
    while (iter != m_pImpl->m_registries.end())
    {
        delete *iter;
        ++iter;
    }
    iter = m_pImpl->m_extra_registries.begin();
    while (iter != m_pImpl->m_extra_registries.end())
    {
        delete *iter;
        ++iter;
    }
}

RegistryKey RegistryTypeManager::searchTypeKey(const OString& name_, sal_Bool * pIsExtraType )
{
    OUString name( OStringToOUString(m_pImpl->m_base + name_, RTL_TEXTENCODING_UTF8) );
    RegistryKey key, rootKey;

    RegistryList::const_iterator iter = m_pImpl->m_registries.begin();
    while (iter != m_pImpl->m_registries.end())
    {
        if (!(*iter)->openRootKey(rootKey))
        {
            if (!rootKey.openKey(name, key))
            {
                if (pIsExtraType)
                    *pIsExtraType = sal_False;
                return key;
            }
        }
        ++iter;
    }
    iter = m_pImpl->m_extra_registries.begin();
    while (iter != m_pImpl->m_extra_registries.end())
    {
        if (!(*iter)->openRootKey(rootKey))
        {
            if (!rootKey.openKey(name, key))
            {
                if (pIsExtraType)
                    *pIsExtraType = sal_True;
                break;
            }
        }
        ++iter;
    }

    return key;
}

<commit_msg>INTEGRATION: CWS sb18 (1.6.4); FILE MERGED 2004/04/28 08:58:49 sb 1.6.4.1: #i21150# Constness improvements.<commit_after>/*************************************************************************
 *
 *  $RCSfile: typemanager.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2004-06-04 03:11:06 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _RTL_ALLOC_H_
#include    <rtl/alloc.h>
#endif

#ifndef _CODEMAKER_TYPEMANAGER_HXX_
#include    <codemaker/typemanager.hxx>
#endif

#include "registry/reader.hxx"
#include "registry/version.h"

using namespace rtl;

TypeManager::TypeManager()
{
    m_pImpl = new TypeManagerImpl();
    acquire();
}

TypeManager::~TypeManager()
{
    release();
}

sal_Int32 TypeManager::acquire()
{
    return osl_incrementInterlockedCount(&m_pImpl->m_refCount);
}

sal_Int32 TypeManager::release()
{
    sal_Int32 refCount = 0;
    if (0 == (refCount = osl_decrementInterlockedCount(&m_pImpl->m_refCount)) )
    {
        delete m_pImpl;
    }
    return refCount;;
}

sal_Bool TypeManager::isBaseType(const ::rtl::OString& name)
{
    if ( name.equals(OString("short")) )
        return sal_True;
    if ( name.equals(OString("unsigned short")) )
        return sal_True;
    if ( name.equals(OString("long")) )
        return sal_True;
    if ( name.equals(OString("unsigned long")) )
        return sal_True;
    if ( name.equals(OString("hyper")) )
        return sal_True;
    if ( name.equals(OString("unsigned hyper")) )
        return sal_True;
    if ( name.equals(OString("string")) )
        return sal_True;
    if ( name.equals(OString("boolean")) )
        return sal_True;
    if ( name.equals(OString("char")) )
        return sal_True;
    if ( name.equals(OString("byte")) )
        return sal_True;
    if ( name.equals(OString("any")) )
        return sal_True;
    if ( name.equals(OString("type")) )
        return sal_True;
    if ( name.equals(OString("float")) )
        return sal_True;
    if ( name.equals(OString("double")) )
        return sal_True;
    if ( name.equals(OString("void")) )
        return sal_True;

    return sal_False;
}

RegistryTypeManager::RegistryTypeManager()
{
    m_pImpl = new RegistryTypeManagerImpl();
    acquire();
}

RegistryTypeManager::~RegistryTypeManager()
{
    release();
}

void RegistryTypeManager::acquire()
{
    TypeManager::acquire();
}

void RegistryTypeManager::release()
{
    if (0 == TypeManager::release())
    {
        freeRegistries();

        delete m_pImpl;
    }
}

sal_Bool RegistryTypeManager::init(
    const StringVector& regFiles,
    StringVector const & extraFiles )
{
    if (regFiles.empty())
        return sal_False;

    StringVector::const_iterator iter = regFiles.begin();

    RegistryLoader loader;
    Registry tmpReg(loader);
    while (iter != regFiles.end())
    {
        if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY))
            m_pImpl->m_registries.push_back(new Registry(tmpReg));
        else
        {
            freeRegistries();
            return sal_False;
        }
        ++iter;
    }
    iter = extraFiles.begin();
    while (iter != extraFiles.end())
    {
        if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY))
            m_pImpl->m_extra_registries.push_back(new Registry(tmpReg));
        else
        {
            freeRegistries();
            return sal_False;
        }
        ++iter;
    }

    return sal_True;
}

typereg::Reader RegistryTypeManager::getTypeReader(
    const OString& name, sal_Bool * pIsExtraType ) const
{
    typereg::Reader reader;
    RegistryKey key(searchTypeKey(name, pIsExtraType));

    if (key.isValid())
    {
        RegValueType    valueType;
        sal_uInt32      valueSize;

        if (!key.getValueInfo(OUString(), &valueType, &valueSize))
        {
            sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
            if (!key.getValue(OUString(), pBuffer))
            {
                reader = typereg::Reader(
                    pBuffer, valueSize, true, TYPEREG_VERSION_1);
            }
            rtl_freeMemory(pBuffer);
        }
    }
    return reader;
}

RTTypeClass RegistryTypeManager::getTypeClass(const OString& name) const
{
    if (m_pImpl->m_t2TypeClass.count(name) > 0)
    {
        return m_pImpl->m_t2TypeClass[name];
    } else
    {
        RegistryKey key(searchTypeKey(name));

        if (key.isValid())
        {
            RegValueType    valueType;
            sal_uInt32      valueSize;

            if (!key.getValueInfo(OUString(), &valueType, &valueSize))
            {
                sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
                if (!key.getValue(OUString(), pBuffer))
                {
                    typereg::Reader reader(
                        pBuffer, valueSize, false, TYPEREG_VERSION_1);

                    RTTypeClass ret = reader.getTypeClass();

                    rtl_freeMemory(pBuffer);

                    m_pImpl->m_t2TypeClass[name] = ret;
                    return ret;
                }
                rtl_freeMemory(pBuffer);
            }
        }
    }

    return RT_TYPE_INVALID;
}

void RegistryTypeManager::setBase(const OString& base)
{
    m_pImpl->m_base = base;

    if (base.lastIndexOf('/') != (base.getLength() - 1))
    {
        m_pImpl->m_base += "/";
    }
}

void RegistryTypeManager::freeRegistries()
{
    RegistryList::const_iterator iter = m_pImpl->m_registries.begin();
    while (iter != m_pImpl->m_registries.end())
    {
        delete *iter;
        ++iter;
    }
    iter = m_pImpl->m_extra_registries.begin();
    while (iter != m_pImpl->m_extra_registries.end())
    {
        delete *iter;
        ++iter;
    }
}

RegistryKey RegistryTypeManager::searchTypeKey(const OString& name_, sal_Bool * pIsExtraType )
    const
{
    OUString name( OStringToOUString(m_pImpl->m_base + name_, RTL_TEXTENCODING_UTF8) );
    RegistryKey key, rootKey;

    RegistryList::const_iterator iter = m_pImpl->m_registries.begin();
    while (iter != m_pImpl->m_registries.end())
    {
        if (!(*iter)->openRootKey(rootKey))
        {
            if (!rootKey.openKey(name, key))
            {
                if (pIsExtraType)
                    *pIsExtraType = sal_False;
                return key;
            }
        }
        ++iter;
    }
    iter = m_pImpl->m_extra_registries.begin();
    while (iter != m_pImpl->m_extra_registries.end())
    {
        if (!(*iter)->openRootKey(rootKey))
        {
            if (!rootKey.openKey(name, key))
            {
                if (pIsExtraType)
                    *pIsExtraType = sal_True;
                break;
            }
        }
        ++iter;
    }

    return key;
}

<|endoftext|>


<commit_before>#include "cglbindingrenderer.h"
#include "coffee/core/graphics_apis/COpenGL"

#include <glbinding/ContextInfo.h>
#include <glbinding/Version.h>
#include <glbinding/callbacks.h>
#include <glbinding/Binding.h>
#include <glbinding/Meta.h>

#include "coffee/core/graphics/opengl_glbinding/glbinding.h"
#include "coffee/core/graphics/cgraphics_quirks.h"

using namespace gl;
using namespace Coffee::CDisplay;

namespace Coffee {
namespace CDisplay {

void glbindingCallbackDirect(GLenum source, GLenum type,GLuint id, GLenum severity,GLsizei length, const GLchar* msg,const void* userPtr);

void glbindingCallbackDirect(GLenum source, GLenum type,
                                             GLuint id, GLenum severity,
                                             GLsizei length, const GLchar* msg,
                                             const void* userPtr)
{
    const CGLBindingRenderer* renderer = static_cast<const CGLBindingRenderer*>(userPtr);
    CGLReport *report = (CGLReport*)c_alloc(sizeof(CGLReport));
    report->source = source;
    report->type = type;
    report->id = id;
    report->message = msg;
    report->severity = severity;
    renderer->bindingCallback(report);
    c_free(report);
}

CGLBindingRenderer::CGLBindingRenderer(Coffee::CObject *parent) :
    CSDL2Renderer(parent),
    m_msg_filter(nullptr),
    m_extensions(nullptr)
{
}

CGLBindingRenderer::~CGLBindingRenderer()
{
    if(m_extensions)
        c_free(m_extensions);
}

void CGLBindingRenderer::fetchGLExtensions()
{
    if(m_extensions)
        c_free(m_extensions);

    GLint exts = 0;
    glGetIntegerv(GL_NUM_EXTENSIONS,&exts);

    CString tmp;

    for(GLint i=0;i<exts;i++){
		byte_t* str = (byte_t*)glGetStringi(GL_EXTENSIONS, i);
		if (!str)
			continue;
        tmp.append(str);
        if(i<exts-1)
            tmp.push_back('\n');
    }

    m_extensions = (cstring_w)c_alloc(tmp.size()+1);
    strcpy(m_extensions,tmp.c_str());
}

bool CGLBindingRenderer::requestGLExtension(cstring ext)
{
    if(!m_extensions){
        if(std::this_thread::get_id()==contextThread())
            fetchGLExtensions();
        else{
            //In case we are on the wrong thread, try queueing a function
            //Will cause a deadlock if functions are not being processed
            cDebug("Failed to acquire extensions: Wrong thread, attempting workaround");
            std::atomic_int* atom = new std::atomic_int();
            atom->store(0);

            queueFunction([=](){
                fetchGLExtensions();
                (*atom)++;
            });

            while(atom->load()<1)
                std::this_thread::sleep_for(std::chrono::microseconds(100));

            return requestGLExtension(ext);
        }
    }
    return strstr(m_extensions,ext);
}

bool CGLBindingRenderer::printExtensions(bool doFetch)
{
    if(!m_extensions){
        if(doFetch)
            fetchGLExtensions();
        else
            return false;
    }

    cDebug("Now printing available extensions");
    cBasicPrint("-----------| Extensions |-----------");
    for(GLextension ext : glbinding::Meta::extensions()){
        cstring extname = glbinding::Meta::getString(ext).c_str();
        bool support = requestGLExtension(extname);
        if(support)
            cBasicPrint("Extension: %s, core version: %s",
                        extname,
                        glbinding::Meta::getRequiringVersion(ext).toString().c_str());
    }
    cBasicPrint("------------------------------------");

    return true;
}

void CGLBindingRenderer::bindingPreInit()
{
    //Check for extensions! Quick!
//    cMsg("glbinding","Initializing glbinding");
    glbinding::Binding::initialize(true);

//    cMsg("glbinding","Initialized");

}

void CGLBindingRenderer::bindingPostInit()
{
    fetchGLExtensions();
    CGraphicsQuirks::coffee_quirks_set_global(this->m_extensions);

    if(m_properties.contextProperties.flags&CGLContextProperties::GLDebug&&
            m_properties.contextProperties.flags&CGLContextProperties::GLPrintExtensions){
        printExtensions(true);
    }

    try{
        m_rendererString        = glbinding::ContextInfo::renderer();
        m_vendorString          = glbinding::ContextInfo::vendor();
        m_versionString         = glbinding::ContextInfo::version().toString();
        m_libraryRevision       = glbinding::Meta::glRevision();
    }
    catch(std::logic_error e){
        cMsg("glbinding","Failed to acquire GL details");
    }

//    cMsg("glbinding","Obtained context information");

    cMsg("glbinding","Currently running OpenGL revision: %i",m_libraryRevision);

//    glbinding::setCallbackMask(glbinding::CallbackMask::After);

//    glbinding::setAfterCallback([](const glbinding::FunctionCall& call){
//        printf("GL call: %s\n",call.function->name());
//    });

    if(m_properties.contextProperties.flags&CGLContextProperties::GLDebug){
        glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
        glDebugMessageCallback((gl::GLDEBUGPROC)glbindingCallbackDirect,this);
    }
}

void CGLBindingRenderer::bindingTerminate()
{
}

void CGLBindingRenderer::bindingCallback(void *report) const
{
    CGLReport* rep = (CGLReport*)report;
    if(!m_msg_filter(rep))
        return;
    CString out = _glbinding_get_string(rep->type)+":"
            +_glbinding_get_string(rep->severity)+":"
            +_glbinding_get_string(rep->source)+": "+rep->message;
    cWarning("OpenGL: %s",out.c_str());
}

cstring CGLBindingRenderer::extensions()
{
    return m_extensions;
}

} // namespace CDisplay
} // namespace Coffee
<commit_msg> - Attempts at fixing Windows GL rendering<commit_after>#include "cglbindingrenderer.h"
#include "coffee/core/graphics_apis/COpenGL"

#include <glbinding/ContextInfo.h>
#include <glbinding/Version.h>
#include <glbinding/callbacks.h>
#include <glbinding/Binding.h>
#include <glbinding/Meta.h>

#include "coffee/core/graphics/opengl_glbinding/glbinding.h"
#include "coffee/core/graphics/cgraphics_quirks.h"

using namespace gl;
using namespace Coffee::CDisplay;

namespace Coffee {
namespace CDisplay {

void glbindingCallbackDirect(GLenum source, GLenum type,GLuint id, GLenum severity,GLsizei length, const GLchar* msg,const void* userPtr);

void glbindingCallbackDirect(GLenum source, GLenum type,
                                             GLuint id, GLenum severity,
                                             GLsizei length, const GLchar* msg,
                                             const void* userPtr)
{
    const CGLBindingRenderer* renderer = static_cast<const CGLBindingRenderer*>(userPtr);
    CGLReport *report = (CGLReport*)c_alloc(sizeof(CGLReport));
    report->source = source;
    report->type = type;
    report->id = id;
    report->message = msg;
    report->severity = severity;
    renderer->bindingCallback(report);
    c_free(report);
}

CGLBindingRenderer::CGLBindingRenderer(Coffee::CObject *parent) :
    CSDL2Renderer(parent),
    m_msg_filter(nullptr),
    m_extensions(nullptr)
{
}

CGLBindingRenderer::~CGLBindingRenderer()
{
    if(m_extensions)
        c_free(m_extensions);
}

void CGLBindingRenderer::fetchGLExtensions()
{
    if(m_extensions)
        c_free(m_extensions);

    GLint exts = 0;
    glGetIntegerv(GL_NUM_EXTENSIONS,&exts);

    CString tmp;

    for(GLint i=0;i<exts;i++){
		const ubyte_t* str = glGetStringi(GL_EXTENSIONS, i);
		if (!str)
			continue;
        tmp.append((cstring)str);
        if(i<exts-1)
            tmp.push_back('\n');
    }

    m_extensions = (cstring_w)c_alloc(tmp.size()+1);
    strcpy(m_extensions,tmp.c_str());
}

bool CGLBindingRenderer::requestGLExtension(cstring ext)
{
    if(!m_extensions){
        if(std::this_thread::get_id()==contextThread())
            fetchGLExtensions();
        else{
            //In case we are on the wrong thread, try queueing a function
            //Will cause a deadlock if functions are not being processed
            cDebug("Failed to acquire extensions: Wrong thread, attempting workaround");
            std::atomic_int* atom = new std::atomic_int();
            atom->store(0);

            queueFunction([=](){
                fetchGLExtensions();
                (*atom)++;
            });

            while(atom->load()<1)
                std::this_thread::sleep_for(std::chrono::microseconds(100));

            return requestGLExtension(ext);
        }
    }
    return strstr(m_extensions,ext);
}

bool CGLBindingRenderer::printExtensions(bool doFetch)
{
    if(!m_extensions){
        if(doFetch)
            fetchGLExtensions();
        else
            return false;
    }

    cDebug("Now printing available extensions");
    cBasicPrint("-----------| Extensions |-----------");
    for(GLextension ext : glbinding::Meta::extensions()){
        cstring extname = glbinding::Meta::getString(ext).c_str();
        bool support = requestGLExtension(extname);
        if(support)
            cBasicPrint("Extension: %s, core version: %s",
                        extname,
                        glbinding::Meta::getRequiringVersion(ext).toString().c_str());
    }
    cBasicPrint("------------------------------------");

    return true;
}

void CGLBindingRenderer::bindingPreInit()
{
    //Check for extensions! Quick!
//    cMsg("glbinding","Initializing glbinding");
    glbinding::Binding::initialize(true);

//    cMsg("glbinding","Initialized");

}

void CGLBindingRenderer::bindingPostInit()
{
    fetchGLExtensions();
    CGraphicsQuirks::coffee_quirks_set_global(this->m_extensions);

    if(m_properties.contextProperties.flags&CGLContextProperties::GLDebug&&
            m_properties.contextProperties.flags&CGLContextProperties::GLPrintExtensions){
        printExtensions(true);
    }

    try{
        m_rendererString        = glbinding::ContextInfo::renderer();
        m_vendorString          = glbinding::ContextInfo::vendor();
        m_versionString         = glbinding::ContextInfo::version().toString();
        m_libraryRevision       = glbinding::Meta::glRevision();
    }
    catch(std::logic_error e){
        cMsg("glbinding","Failed to acquire GL details");
    }

//    cMsg("glbinding","Obtained context information");

    cMsg("glbinding","Currently running OpenGL revision: %i",m_libraryRevision);

//    glbinding::setCallbackMask(glbinding::CallbackMask::After);

//    glbinding::setAfterCallback([](const glbinding::FunctionCall& call){
//        printf("GL call: %s\n",call.function->name());
//    });

    if(m_properties.contextProperties.flags&CGLContextProperties::GLDebug){
        glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
        glDebugMessageCallback((gl::GLDEBUGPROC)glbindingCallbackDirect,this);
    }
}

void CGLBindingRenderer::bindingTerminate()
{
}

void CGLBindingRenderer::bindingCallback(void *report) const
{
    CGLReport* rep = (CGLReport*)report;
    if(!m_msg_filter(rep))
        return;
    CString out = _glbinding_get_string(rep->type)+":"
            +_glbinding_get_string(rep->severity)+":"
            +_glbinding_get_string(rep->source)+": "+rep->message;
    cWarning("OpenGL: %s",out.c_str());
}

cstring CGLBindingRenderer::extensions()
{
    return m_extensions;
}

} // namespace CDisplay
} // namespace Coffee
<|endoftext|>


<commit_before>/* -*- c-basic-offset: 2 -*- */
/*
  Copyright(C) 2010 Tetsuro IKEDA
  Copyright(C) 2011-2012 Kentoku SHIBA
  Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  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
*/

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "mrn_path_mapper.hpp"

#include <string.h>

namespace mrn {
  PathMapper::PathMapper(const char *mysql_path, const char *path_prefix)
    : mysql_path_(mysql_path),
      path_prefix_(path_prefix) {
    db_path_[0] = '\0';
    db_name_[0] = '\0';
    table_name_[0] = '\0';
    mysql_table_name_[0] = '\0';
  }

  /**
   * "./${db}/${table}"                              ==> "${db}.mrn"
   * "./${db}/"                                      ==> "${db}.mrn"
   * "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0" ==>
   *   "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0.mrn"
   */
  const char *PathMapper::db_path() {
    if (db_path_[0] != '\0') {
      return db_path_;
    }

    if (strncmp(mysql_path_, "./", 2) == 0) {
      if (path_prefix_) {
        strncat(db_path_, path_prefix_, MRN_MAX_PATH_SIZE);
      }

      int i = 2, j = strlen(db_path_), len;
      len = strlen(mysql_path_);
      while (mysql_path_[i] != '/' && i < len) {
        db_path_[j++] = mysql_path_[i++];
      }
      db_path_[j] = '\0';
    } else {
      strcpy(db_path_, mysql_path_);
    }
    strcat(db_path_, MRN_DB_FILE_SUFFIX);
    return db_path_;
  }

  /**
   * "./${db}/${table}"                              ==> "${db}"
   * "./${db}/"                                      ==> "${db}"
   * "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0" ==>
   *   "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0"
   */
  const char *PathMapper::db_name() {
    if (db_name_[0] != '\0') {
      return db_name_;
    }

    if (strncmp(mysql_path_, "./", 2) == 0) {
      int i = 2, j = 0, len;
      len = strlen(mysql_path_);
      while (mysql_path_[i] != '/' && i < len) {
        db_name_[j++] = mysql_path_[i++];
      }
      db_name_[j] = '\0';
    } else {
      strcpy(db_name_, mysql_path_);
    }
    return db_name_;
  }

  /**
   * "./${db}/${table}" ==> "${table}" (with encoding first '_')
   */
  const char *PathMapper::table_name() {
    if (table_name_[0] != '\0') {
      return table_name_;
    }

    int len = strlen(mysql_path_);
    int i = len, j = 0;
    for (; mysql_path_[--i] != '/' ;) {}
    if (mysql_path_[i + 1] == '_') {
      table_name_[j++] = '@';
      table_name_[j++] = '0';
      table_name_[j++] = '0';
      table_name_[j++] = '5';
      table_name_[j++] = 'f';
      i++;
    }
    for (; i < len ;) {
      table_name_[j++] = mysql_path_[++i];
    }
    table_name_[j] = '\0';
    return table_name_;
  }

  /**
   * "./${db}/${table}" ==> "${table}" (without encoding first '_')
   */
  const char *PathMapper::mysql_table_name() {
    if (mysql_table_name_[0] != '\0') {
      return mysql_table_name_;
    }

    int len = strlen(mysql_path_);
    int i = len, j = 0;
    for (; mysql_path_[--i] != '/' ;) {}
    for (; i < len ;) {
      mysql_table_name_[j++] = mysql_path_[++i];
    }
    mysql_table_name_[j] = '\0';
    return mysql_table_name_;
  }
}
<commit_msg>Eliminate the possibility of buffer overflow<commit_after>/* -*- c-basic-offset: 2 -*- */
/*
  Copyright(C) 2010 Tetsuro IKEDA
  Copyright(C) 2011-2012 Kentoku SHIBA
  Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  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
*/

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "mrn_path_mapper.hpp"

#include <string.h>

namespace mrn {
  PathMapper::PathMapper(const char *mysql_path, const char *path_prefix)
    : mysql_path_(mysql_path),
      path_prefix_(path_prefix) {
    db_path_[0] = '\0';
    db_name_[0] = '\0';
    table_name_[0] = '\0';
    mysql_table_name_[0] = '\0';
  }

  /**
   * "./${db}/${table}"                              ==> "${db}.mrn"
   * "./${db}/"                                      ==> "${db}.mrn"
   * "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0" ==>
   *   "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0.mrn"
   */
  const char *PathMapper::db_path() {
    if (db_path_[0] != '\0') {
      return db_path_;
    }

    size_t db_len = strlen(db_path_);
    if (strncmp(mysql_path_, "./", 2) == 0) {
      if (path_prefix_) {
        strncat(db_path_, path_prefix_, MRN_MAX_PATH_SIZE - db_len - 1);
      }

      int i = 2, j = strlen(db_path_), len;
      len = strlen(mysql_path_);
      while (mysql_path_[i] != '/' && i < len) {
        db_path_[j++] = mysql_path_[i++];
      }
      db_path_[j] = '\0';
    } else {
      strcpy(db_path_, mysql_path_);
    }
    strcat(db_path_, MRN_DB_FILE_SUFFIX);
    return db_path_;
  }

  /**
   * "./${db}/${table}"                              ==> "${db}"
   * "./${db}/"                                      ==> "${db}"
   * "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0" ==>
   *   "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0"
   */
  const char *PathMapper::db_name() {
    if (db_name_[0] != '\0') {
      return db_name_;
    }

    if (strncmp(mysql_path_, "./", 2) == 0) {
      int i = 2, j = 0, len;
      len = strlen(mysql_path_);
      while (mysql_path_[i] != '/' && i < len) {
        db_name_[j++] = mysql_path_[i++];
      }
      db_name_[j] = '\0';
    } else {
      strcpy(db_name_, mysql_path_);
    }
    return db_name_;
  }

  /**
   * "./${db}/${table}" ==> "${table}" (with encoding first '_')
   */
  const char *PathMapper::table_name() {
    if (table_name_[0] != '\0') {
      return table_name_;
    }

    int len = strlen(mysql_path_);
    int i = len, j = 0;
    for (; mysql_path_[--i] != '/' ;) {}
    if (mysql_path_[i + 1] == '_') {
      table_name_[j++] = '@';
      table_name_[j++] = '0';
      table_name_[j++] = '0';
      table_name_[j++] = '5';
      table_name_[j++] = 'f';
      i++;
    }
    for (; i < len ;) {
      table_name_[j++] = mysql_path_[++i];
    }
    table_name_[j] = '\0';
    return table_name_;
  }

  /**
   * "./${db}/${table}" ==> "${table}" (without encoding first '_')
   */
  const char *PathMapper::mysql_table_name() {
    if (mysql_table_name_[0] != '\0') {
      return mysql_table_name_;
    }

    int len = strlen(mysql_path_);
    int i = len, j = 0;
    for (; mysql_path_[--i] != '/' ;) {}
    for (; i < len ;) {
      mysql_table_name_[j++] = mysql_path_[++i];
    }
    mysql_table_name_[j] = '\0';
    return mysql_table_name_;
  }
}
<|endoftext|>