<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: QTableConnection.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 10:37:32 $
 *
 *  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
 *
 ************************************************************************/
#ifndef DBAUI_QUERYTABLECONNECTION_HXX
#define DBAUI_QUERYTABLECONNECTION_HXX

#ifndef DBAUI_TABLECONNECTION_HXX
#include "TableConnection.hxx"
#endif
#ifndef DBAUI_QTABLECONNECTIONDATA_HXX
#include "QTableConnectionData.hxx"
#endif
#ifndef DBAUI_ENUMTYPES_HXX
#include "QEnumTypes.hxx"
#endif

namespace dbaui
{
    //==================================================================
    class OQueryTableView;
    class OQueryTableConnection : public OTableConnection
    {
        sal_Bool m_bVisited;    // is true if the conn was already visited through the join algorithm
    public:
        TYPEINFO();
        OQueryTableConnection(OQueryTableView* pContainer, OQueryTableConnectionData* pTabConnData);
        OQueryTableConnection(const OQueryTableConnection& rConn);
        virtual ~OQueryTableConnection();

        OQueryTableConnection& operator=(const OQueryTableConnection& rConn);
        sal_Bool operator==(const OQueryTableConnection& rCompare);

        ::rtl::OUString GetAliasName(EConnectionSide nWhich) const { return static_cast<OQueryTableConnectionData*>(GetData())->GetAliasName(nWhich); }

        sal_Bool    IsVisited() const               { return m_bVisited; }
        void        SetVisited(sal_Bool bVisited)   { m_bVisited = bVisited; }

    };
}
#endif // DBAUI_QUERYTABLECONNECTION_HXX
<commit_msg>INTEGRATION: CWS dba24b (1.4.46); FILE MERGED 2007/08/16 06:14:44 oj 1.4.46.1: #i56898# clean up of the class structure<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: QTableConnection.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-11-01 15:29:45 $
 *
 *  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
 *
 ************************************************************************/
#ifndef DBAUI_QUERYTABLECONNECTION_HXX
#define DBAUI_QUERYTABLECONNECTION_HXX

#ifndef DBAUI_TABLECONNECTION_HXX
#include "TableConnection.hxx"
#endif
#ifndef DBAUI_QTABLECONNECTIONDATA_HXX
#include "QTableConnectionData.hxx"
#endif
#ifndef DBAUI_ENUMTYPES_HXX
#include "QEnumTypes.hxx"
#endif

namespace dbaui
{
    //==================================================================
    class OQueryTableView;
    class OQueryTableConnection : public OTableConnection
    {
        sal_Bool m_bVisited;    // is true if the conn was already visited through the join algorithm
    public:
        OQueryTableConnection(OQueryTableView* pContainer, const TTableConnectionData::value_type& pTabConnData);
        OQueryTableConnection(const OQueryTableConnection& rConn);
        virtual ~OQueryTableConnection();

        OQueryTableConnection& operator=(const OQueryTableConnection& rConn);
        sal_Bool operator==(const OQueryTableConnection& rCompare);

        inline ::rtl::OUString  GetAliasName(EConnectionSide nWhich) const { return static_cast<OQueryTableConnectionData*>(GetData().get())->GetAliasName(nWhich); }

        inline sal_Bool IsVisited() const               { return m_bVisited; }
        inline void     SetVisited(sal_Bool bVisited)   { m_bVisited = bVisited; }

    };
}
#endif // DBAUI_QUERYTABLECONNECTION_HXX
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: setup_help.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 17:54:33 $
 *
 *  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
 *
 ************************************************************************/

#ifndef SETUP_HELP_HXX
#define SETUP_HELP_HXX

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

#ifdef UNICODE
#else
 #define LanguageDataX   LanguageDataA
#endif

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

class SetupHelperX
{
};

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

#endif<commit_msg>INTEGRATION: CWS changefileheader (1.4.614); FILE MERGED 2008/03/28 15:27:23 rt 1.4.614.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: setup_help.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SETUP_HELP_HXX
#define SETUP_HELP_HXX

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

#ifdef UNICODE
#else
 #define LanguageDataX   LanguageDataA
#endif

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

class SetupHelperX
{
};

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

#endif<|endoftext|>


<commit_before>//--------------------------------------------------------------------------------------------------
/**
 * @file moduleBuildScript.cpp
 *
 * Implementation of the build script generator for pre-built kernel modules.
 *
 *

 *
 * Copyright (C) Sierra Wireless Inc.
 */
//--------------------------------------------------------------------------------------------------

#include "mkTools.h"
#include "buildScriptCommon.h"
#include "moduleBuildScript.h"

namespace ninja
{

//--------------------------------------------------------------------------------------------------
/**
 * Generate comment header for a build script.
 */
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::GenerateCommentHeader
(
    model::Module_t* modulePtr
)
//--------------------------------------------------------------------------------------------------
{
    script  << "# Build script for module '" << modulePtr->name << "'\n"
               "\n"
               "# == Auto-generated file.  Do not edit. ==\n"
               "\n";
}

//--------------------------------------------------------------------------------------------------
/**
 * Print to a given build script the build statements related to a given module.
 * If it's a pre-built module, just copy it. Otherwise generate a module Makefile and build it.
 **/
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::GenerateBuildStatements
(
    model::Module_t* modulePtr
)
//--------------------------------------------------------------------------------------------------
{
    if (modulePtr->moduleBuildType == model::Module_t::Sources)
    {
        // In case of Sources, koFiles map will consist of only one element.
        // Hence, use the first element in koFiles for generating build statement.
        auto const it = modulePtr->koFiles.begin();
        if (it != modulePtr->koFiles.end())
        {
            script << "build " << "$builddir/" << it->second->path << ": ";

            // No pre-built module: generate and invoke a Makefile
            GenerateMakefile(modulePtr);
            script << "MakeKernelModule " << "$builddir/"
                   << path::GetContainingDir(it->second->path) << "\n";
        }
        else
        {
            throw mk::Exception_t(
                      mk::format(LE_I18N("error: %s container of kernel object file is empty."),
                                 modulePtr->defFilePtr->path));
        }
    }
    else if (modulePtr->moduleBuildType == model::Module_t::Prebuilt)
    {
        for (auto const& it: modulePtr->koFiles)
        {
            script << "build " << "$builddir/" << it.second->path << ": ";

            // Pre-built module: add build statement for bundling the .ko file
            script << "BundleFile " << it.first << "\n"
                   << "  modeFlags = u+rw-x,g+r-wx,o+r-wx\n";
        }
    }
    else
    {
        throw mk::Exception_t(
                  mk::format(LE_I18N("error: %s must have either 'sources' or 'preBuilt' section."),
                              modulePtr->defFilePtr->path));
    }
    script << "\n";
}

//--------------------------------------------------------------------------------------------------
/**
 * Write to a given build script the build statements for the build script itself.
 **/
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::GenerateNinjaScriptBuildStatement
(
    model::Module_t* modulePtr
)
//--------------------------------------------------------------------------------------------------
{
    // The build.ninja depends on module .mdef and .ko files
    // Create a set of dependencies.
    std::set<std::string> dependencies;

    for (auto const& it : modulePtr->koFiles)
    {
        dependencies.insert(it.first);
    }

    dependencies.insert(modulePtr->defFilePtr->path);
    // It also depends on changes to the mk tools.
    dependencies.insert(path::Combine(envVars::Get("LEGATO_ROOT"), "build/tools/mk"));

    baseGeneratorPtr->GenerateNinjaScriptBuildStatement(dependencies);
}

//--------------------------------------------------------------------------------------------------
/**
 * Generate a Makefile for a kernel module.
 **/
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::GenerateMakefile
(
    model::Module_t* modulePtr
)
//--------------------------------------------------------------------------------------------------
{
    std::string buildPath = path::MakeAbsolute(buildParams.workingDir
                                + "/modules/" + modulePtr->name);
    const std::string& compilerPath = buildParams.cCompilerPath;

    std::ofstream makefile;
    OpenFile(makefile, buildPath + "/Makefile", buildParams.beVerbose);

    // Specify kernel module name and list all object files to link
    makefile << "obj-m += " << modulePtr->name << ".o\n";

    // Don't list object files in case of a single source file with module name
    if (modulePtr->cObjectFiles.size() > 1 ||
        modulePtr->cObjectFiles.front()->path != modulePtr->name + ".o")
    {
        for (auto obj : modulePtr->cObjectFiles)
        {
            makefile << modulePtr->name << "-objs += " << obj->path << "\n";
        }
    }
    makefile << "\n";

    // Specify directory where the sources are located
    makefile << "src = " << modulePtr->dir << "\n\n";

    // Add compiler and linker options
    for (auto const &obj : modulePtr->cFlags)
    {
        makefile << "ccflags-y += " << obj << "\n";
    }
    for (auto const &obj : modulePtr->ldFlags)
    {
        makefile << "ldflags-y += " << obj << "\n";
    }
    makefile << "\n";

    makefile << "KBUILD := " << modulePtr->kernelDir << "\n";

    if (buildParams.target != "localhost")
    {
        // Specify the CROSS_COMPILE and ARCH environment variables
        // Note: compiler path may contain dashes in directory names
        std::string compiler = path::GetLastNode(compilerPath);
        std::string cross = path::GetContainingDir(compilerPath) + "/"
                                + compiler.substr(0, compiler.rfind('-') + 1);
        std::string arch = compiler.substr(0, compiler.find('-'));

        makefile << "export CROSS_COMPILE := " << cross << "\n";
        makefile << "export ARCH := " << arch << "\n";
    }
    makefile << "\n";

    // Specify build rules
    makefile << "all:\n";
    makefile << "\tmake -C $(KBUILD) M=" + buildPath + " modules\n";
    makefile << "\n";
    makefile << "clean:\n";
    makefile << "\t make -C $(KBUILD) M=" + buildPath + " clean\n";

    CloseFile(makefile);
}

//--------------------------------------------------------------------------------------------------
/**
 * Generate a build script for a pre-built kernel module.
 */
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::Generate
(
    model::Module_t* modulePtr
)
{
    // Start the script with a comment, the file-level variable definitions, and
    // a set of generic rules.
    GenerateCommentHeader(modulePtr);
    script << "builddir = " << path::MakeAbsolute(buildParams.workingDir) << "\n\n";
    script << "target = " << buildParams.target << "\n\n";
    baseGeneratorPtr->GenerateIfgenFlagsDef();
    baseGeneratorPtr->GenerateBuildRules();

    if (!buildParams.codeGenOnly)
    {
        // Add build statements for the module.
        GenerateBuildStatements(modulePtr);
    }

    // Add a build statement for the build.ninja file itself.
    GenerateNinjaScriptBuildStatement(modulePtr);
}

//--------------------------------------------------------------------------------------------------
/**
 * Generate a build script for a pre-built kernel module.
 **/
//--------------------------------------------------------------------------------------------------
void Generate
(
    model::Module_t* modulePtr,
    const mk::BuildParams_t& buildParams
)
//--------------------------------------------------------------------------------------------------
{
    std::string filePath = path::Minimize(buildParams.workingDir + "/build.ninja");

    ModuleBuildScriptGenerator_t scriptGenerator(filePath, buildParams);
    scriptGenerator.Generate(modulePtr);
}

} // namespace ninja
<commit_msg>[kernelModules] Fix incorrect kernel arch for i586<commit_after>//--------------------------------------------------------------------------------------------------
/**
 * @file moduleBuildScript.cpp
 *
 * Implementation of the build script generator for pre-built kernel modules.
 *
 *

 *
 * Copyright (C) Sierra Wireless Inc.
 */
//--------------------------------------------------------------------------------------------------

#include "mkTools.h"
#include "buildScriptCommon.h"
#include "moduleBuildScript.h"

namespace ninja
{

//--------------------------------------------------------------------------------------------------
/**
 * Generate comment header for a build script.
 */
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::GenerateCommentHeader
(
    model::Module_t* modulePtr
)
//--------------------------------------------------------------------------------------------------
{
    script  << "# Build script for module '" << modulePtr->name << "'\n"
               "\n"
               "# == Auto-generated file.  Do not edit. ==\n"
               "\n";
}

//--------------------------------------------------------------------------------------------------
/**
 * Print to a given build script the build statements related to a given module.
 * If it's a pre-built module, just copy it. Otherwise generate a module Makefile and build it.
 **/
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::GenerateBuildStatements
(
    model::Module_t* modulePtr
)
//--------------------------------------------------------------------------------------------------
{
    if (modulePtr->moduleBuildType == model::Module_t::Sources)
    {
        // In case of Sources, koFiles map will consist of only one element.
        // Hence, use the first element in koFiles for generating build statement.
        auto const it = modulePtr->koFiles.begin();
        if (it != modulePtr->koFiles.end())
        {
            script << "build " << "$builddir/" << it->second->path << ": ";

            // No pre-built module: generate and invoke a Makefile
            GenerateMakefile(modulePtr);
            script << "MakeKernelModule " << "$builddir/"
                   << path::GetContainingDir(it->second->path) << "\n";
        }
        else
        {
            throw mk::Exception_t(
                      mk::format(LE_I18N("error: %s container of kernel object file is empty."),
                                 modulePtr->defFilePtr->path));
        }
    }
    else if (modulePtr->moduleBuildType == model::Module_t::Prebuilt)
    {
        for (auto const& it: modulePtr->koFiles)
        {
            script << "build " << "$builddir/" << it.second->path << ": ";

            // Pre-built module: add build statement for bundling the .ko file
            script << "BundleFile " << it.first << "\n"
                   << "  modeFlags = u+rw-x,g+r-wx,o+r-wx\n";
        }
    }
    else
    {
        throw mk::Exception_t(
                  mk::format(LE_I18N("error: %s must have either 'sources' or 'preBuilt' section."),
                              modulePtr->defFilePtr->path));
    }
    script << "\n";
}

//--------------------------------------------------------------------------------------------------
/**
 * Write to a given build script the build statements for the build script itself.
 **/
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::GenerateNinjaScriptBuildStatement
(
    model::Module_t* modulePtr
)
//--------------------------------------------------------------------------------------------------
{
    // The build.ninja depends on module .mdef and .ko files
    // Create a set of dependencies.
    std::set<std::string> dependencies;

    for (auto const& it : modulePtr->koFiles)
    {
        dependencies.insert(it.first);
    }

    dependencies.insert(modulePtr->defFilePtr->path);
    // It also depends on changes to the mk tools.
    dependencies.insert(path::Combine(envVars::Get("LEGATO_ROOT"), "build/tools/mk"));

    baseGeneratorPtr->GenerateNinjaScriptBuildStatement(dependencies);
}

//--------------------------------------------------------------------------------------------------
/**
 * Generate a Makefile for a kernel module.
 **/
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::GenerateMakefile
(
    model::Module_t* modulePtr
)
//--------------------------------------------------------------------------------------------------
{
    std::string buildPath = path::MakeAbsolute(buildParams.workingDir
                                + "/modules/" + modulePtr->name);
    const std::string& compilerPath = buildParams.cCompilerPath;

    std::ofstream makefile;
    OpenFile(makefile, buildPath + "/Makefile", buildParams.beVerbose);

    // Specify kernel module name and list all object files to link
    makefile << "obj-m += " << modulePtr->name << ".o\n";

    // Don't list object files in case of a single source file with module name
    if (modulePtr->cObjectFiles.size() > 1 ||
        modulePtr->cObjectFiles.front()->path != modulePtr->name + ".o")
    {
        for (auto obj : modulePtr->cObjectFiles)
        {
            makefile << modulePtr->name << "-objs += " << obj->path << "\n";
        }
    }
    makefile << "\n";

    // Specify directory where the sources are located
    makefile << "src = " << modulePtr->dir << "\n\n";

    // Add compiler and linker options
    for (auto const &obj : modulePtr->cFlags)
    {
        makefile << "ccflags-y += " << obj << "\n";
    }
    for (auto const &obj : modulePtr->ldFlags)
    {
        makefile << "ldflags-y += " << obj << "\n";
    }
    makefile << "\n";

    makefile << "KBUILD := " << modulePtr->kernelDir << "\n";

    if (buildParams.target != "localhost")
    {
        // Specify the CROSS_COMPILE and ARCH environment variables
        // Note: compiler path may contain dashes in directory names
        std::string compiler = path::GetLastNode(compilerPath);
        std::string cross = path::GetContainingDir(compilerPath) + "/"
                                + compiler.substr(0, compiler.rfind('-') + 1);
        std::string arch = compiler.substr(0, compiler.find('-'));
        if ((arch == "i586") || (arch == "i686"))
        {
            arch = "x86";
        }

        makefile << "export CROSS_COMPILE := " << cross << "\n";
        makefile << "export ARCH := " << arch << "\n";
    }
    makefile << "\n";

    // Specify build rules
    makefile << "all:\n";
    makefile << "\tmake -C $(KBUILD) M=" + buildPath + " modules\n";
    makefile << "\n";
    makefile << "clean:\n";
    makefile << "\t make -C $(KBUILD) M=" + buildPath + " clean\n";

    CloseFile(makefile);
}

//--------------------------------------------------------------------------------------------------
/**
 * Generate a build script for a pre-built kernel module.
 */
//--------------------------------------------------------------------------------------------------
void ModuleBuildScriptGenerator_t::Generate
(
    model::Module_t* modulePtr
)
{
    // Start the script with a comment, the file-level variable definitions, and
    // a set of generic rules.
    GenerateCommentHeader(modulePtr);
    script << "builddir = " << path::MakeAbsolute(buildParams.workingDir) << "\n\n";
    script << "target = " << buildParams.target << "\n\n";
    baseGeneratorPtr->GenerateIfgenFlagsDef();
    baseGeneratorPtr->GenerateBuildRules();

    if (!buildParams.codeGenOnly)
    {
        // Add build statements for the module.
        GenerateBuildStatements(modulePtr);
    }

    // Add a build statement for the build.ninja file itself.
    GenerateNinjaScriptBuildStatement(modulePtr);
}

//--------------------------------------------------------------------------------------------------
/**
 * Generate a build script for a pre-built kernel module.
 **/
//--------------------------------------------------------------------------------------------------
void Generate
(
    model::Module_t* modulePtr,
    const mk::BuildParams_t& buildParams
)
//--------------------------------------------------------------------------------------------------
{
    std::string filePath = path::Minimize(buildParams.workingDir + "/build.ninja");

    ModuleBuildScriptGenerator_t scriptGenerator(filePath, buildParams);
    scriptGenerator.Generate(modulePtr);
}

} // namespace ninja
<|endoftext|>


<commit_before>#include <cstdio>
#include <string>
#include "catch.hh"
#include "lib/File.h"
#include "test_crc_support.h"

void test_computing(const CRC &crc, CRCType checksum)
{
    Progress progress;
    std::string content = "123456789";

    auto inFile = File::fromFileName(
        "test-in.txt",
        File::Mode::Write | File::Mode::Read | File::Mode::Binary);

    inFile->write(content.data(), content.size());
    inFile->seek(0, File::Origin::Start);
    REQUIRE(crc.computeChecksum(*inFile, progress) == checksum);

    std::remove("test-in.txt");
}

void test_appending(const CRC &crc, CRCType checksum)
{
    Progress progress;
    std::string content = "test content";

    {
        auto inFile = File::fromFileName("test-in.txt", File::Mode::Write);
        inFile->write(content.data(), content.size());
        REQUIRE(inFile->getSize() == content.size());
    }

    auto size1 = content.size();
    auto size2 = size1 + crc.getSpecs().numBytes;
    {
        auto inFile = File::fromFileName(
            "test-in.txt", File::Mode::Read | File::Mode::Binary);
        auto outFile = File::fromFileName(
            "test-out.txt", File::Mode::Write | File::Mode::Binary);
        crc.applyPatch(
            checksum, size1, *inFile, *outFile, false, progress, progress);
    }

    {
        auto inFile = File::fromFileName(
            "test-out.txt", File::Mode::Read | File::Mode::Binary);
        REQUIRE(inFile->getSize() == size2);
        REQUIRE(crc.computeChecksum(*inFile, progress) == checksum);

        std::unique_ptr<char[]> buf(new char[size1]);
        inFile->seek(0, File::Origin::Start);
        inFile->read(buf.get(), size1);
        REQUIRE(std::string(buf.get()) == content);
        std::remove("test-in.txt");
        std::remove("test-out.txt");
    }
}

void test_inserting(const CRC &crc, CRCType checksum)
{
    Progress progress;
    std::string content = "test content";

    {
        auto inFile = File::fromFileName("test-in.txt", File::Mode::Write);
        inFile->write(content.data(), content.size());
        REQUIRE(inFile->getSize() == content.size());
    }

    size_t offset1 = content.size() / 2;
    size_t offset2 = offset1 + crc.getSpecs().numBytes;
    size_t size = content.size() + crc.getSpecs().numBytes;

    {
        auto inFile = File::fromFileName(
            "test-in.txt", File::Mode::Read | File::Mode::Binary);
        auto outFile = File::fromFileName(
            "test-out.txt", File::Mode::Write | File::Mode::Binary);
        crc.applyPatch(
            checksum, offset1, *inFile, *outFile, false, progress, progress);
    }

    {
        auto inFile = File::fromFileName(
            "test-out.txt", File::Mode::Read | File::Mode::Binary);
        REQUIRE(inFile->getSize() == size);
        REQUIRE(crc.computeChecksum(*inFile, progress) == checksum);

        std::unique_ptr<char[]> buf(new char[size]);
        inFile->seek(0, File::Origin::Start);
        inFile->read(buf.get(), size);
        REQUIRE(std::string(buf.get(), offset1) == content.substr(0, offset1));
        REQUIRE(std::string(buf.get() + offset2, size - offset2)
            == content.substr(offset1, size - offset2));
        std::remove("test-in.txt");
        std::remove("test-out.txt");
    }
}

void test_overwriting(const CRC &crc, CRCType checksum)
{
    Progress progress;
    std::string content = "test content";

    {
        auto inFile = File::fromFileName("test-in.txt", File::Mode::Write);
        inFile->write(content.data(), content.size());
        REQUIRE(inFile->getSize() == content.size());
    }

    size_t offset = content.size() - crc.getSpecs().numBytes;

    {
        auto inFile = File::fromFileName(
            "test-in.txt", File::Mode::Read | File::Mode::Binary);
        auto outFile = File::fromFileName(
            "test-out.txt", File::Mode::Write | File::Mode::Binary);
        crc.applyPatch(
            checksum, offset, *inFile, *outFile, true, progress, progress);
    }

    {
        auto inFile = File::fromFileName(
            "test-out.txt", File::Mode::Read | File::Mode::Binary);
        REQUIRE(inFile->getSize() == content.size());
        REQUIRE(crc.computeChecksum(*inFile, progress) == checksum);

        std::unique_ptr<char[]> buf(new char[offset]);
        inFile->seek(0, File::Origin::Start);
        inFile->read(buf.get(), offset);
        REQUIRE(std::string(buf.get(), offset) == content.substr(0, offset));
        std::remove("test-in.txt");
        std::remove("test-out.txt");
    }
}
<commit_msg>Fixed buffer overflow in tests<commit_after>#include <cstdio>
#include <string>
#include "catch.hh"
#include "lib/File.h"
#include "test_crc_support.h"

void test_computing(const CRC &crc, CRCType checksum)
{
    Progress progress;
    std::string content = "123456789";

    auto inFile = File::fromFileName(
        "test-in.txt",
        File::Mode::Write | File::Mode::Read | File::Mode::Binary);

    inFile->write(content.data(), content.size());
    inFile->seek(0, File::Origin::Start);
    REQUIRE(crc.computeChecksum(*inFile, progress) == checksum);

    std::remove("test-in.txt");
}

void test_appending(const CRC &crc, CRCType checksum)
{
    Progress progress;
    std::string content = "test content";

    {
        auto inFile = File::fromFileName("test-in.txt", File::Mode::Write);
        inFile->write(content.data(), content.size());
        REQUIRE(inFile->getSize() == content.size());
    }

    auto size1 = content.size();
    auto size2 = size1 + crc.getSpecs().numBytes;
    {
        auto inFile = File::fromFileName(
            "test-in.txt", File::Mode::Read | File::Mode::Binary);
        auto outFile = File::fromFileName(
            "test-out.txt", File::Mode::Write | File::Mode::Binary);
        crc.applyPatch(
            checksum, size1, *inFile, *outFile, false, progress, progress);
    }

    {
        auto inFile = File::fromFileName(
            "test-out.txt", File::Mode::Read | File::Mode::Binary);
        REQUIRE(inFile->getSize() == size2);
        REQUIRE(crc.computeChecksum(*inFile, progress) == checksum);

        std::unique_ptr<char[]> buf(new char[size1]);
        inFile->seek(0, File::Origin::Start);
        inFile->read(buf.get(), size1);
        REQUIRE(std::string(buf.get(), size1) == content.substr(0, size1));
        std::remove("test-in.txt");
        std::remove("test-out.txt");
    }
}

void test_inserting(const CRC &crc, CRCType checksum)
{
    Progress progress;
    std::string content = "test content";

    {
        auto inFile = File::fromFileName("test-in.txt", File::Mode::Write);
        inFile->write(content.data(), content.size());
        REQUIRE(inFile->getSize() == content.size());
    }

    size_t offset1 = content.size() / 2;
    size_t offset2 = offset1 + crc.getSpecs().numBytes;
    size_t size = content.size() + crc.getSpecs().numBytes;

    {
        auto inFile = File::fromFileName(
            "test-in.txt", File::Mode::Read | File::Mode::Binary);
        auto outFile = File::fromFileName(
            "test-out.txt", File::Mode::Write | File::Mode::Binary);
        crc.applyPatch(
            checksum, offset1, *inFile, *outFile, false, progress, progress);
    }

    {
        auto inFile = File::fromFileName(
            "test-out.txt", File::Mode::Read | File::Mode::Binary);
        REQUIRE(inFile->getSize() == size);
        REQUIRE(crc.computeChecksum(*inFile, progress) == checksum);

        std::unique_ptr<char[]> buf(new char[size]);
        inFile->seek(0, File::Origin::Start);
        inFile->read(buf.get(), size);
        REQUIRE(std::string(buf.get(), offset1) == content.substr(0, offset1));
        REQUIRE(std::string(buf.get() + offset2, size - offset2)
            == content.substr(offset1, size - offset2));
        std::remove("test-in.txt");
        std::remove("test-out.txt");
    }
}

void test_overwriting(const CRC &crc, CRCType checksum)
{
    Progress progress;
    std::string content = "test content";

    {
        auto inFile = File::fromFileName("test-in.txt", File::Mode::Write);
        inFile->write(content.data(), content.size());
        REQUIRE(inFile->getSize() == content.size());
    }

    size_t offset = content.size() - crc.getSpecs().numBytes;

    {
        auto inFile = File::fromFileName(
            "test-in.txt", File::Mode::Read | File::Mode::Binary);
        auto outFile = File::fromFileName(
            "test-out.txt", File::Mode::Write | File::Mode::Binary);
        crc.applyPatch(
            checksum, offset, *inFile, *outFile, true, progress, progress);
    }

    {
        auto inFile = File::fromFileName(
            "test-out.txt", File::Mode::Read | File::Mode::Binary);
        REQUIRE(inFile->getSize() == content.size());
        REQUIRE(crc.computeChecksum(*inFile, progress) == checksum);

        std::unique_ptr<char[]> buf(new char[offset]);
        inFile->seek(0, File::Origin::Start);
        inFile->read(buf.get(), offset);
        REQUIRE(std::string(buf.get(), offset) == content.substr(0, offset));
        std::remove("test-in.txt");
        std::remove("test-out.txt");
    }
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>
#include <jni.h>

#include "webrtc/modules/audio_device/android/audio_device_template.h"
#include "webrtc/modules/audio_device/android/audio_record_jni.h"
#include "webrtc/modules/audio_device/android/audio_track_jni.h"
#include "webrtc/modules/audio_device/android/opensles_input.h"
#include "webrtc/modules/audio_device/android/opensles_output.h"
#include "webrtc/modules/audio_device/android/test/fake_audio_device_buffer.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"

// Java globals
static JavaVM* g_vm = NULL;
static jclass g_osr = NULL;

namespace webrtc {

template <class InputType, class OutputType>
class OpenSlRunnerTemplate {
 public:
  OpenSlRunnerTemplate()
      : output_(0),
        input_(0, &output_) {
    output_.AttachAudioBuffer(&audio_buffer_);
    if (output_.Init() != 0) {
      assert(false);
    }
    if (output_.InitPlayout() != 0) {
      assert(false);
    }
    input_.AttachAudioBuffer(&audio_buffer_);
    if (input_.Init() != 0) {
      assert(false);
    }
    if (input_.InitRecording() != 0) {
      assert(false);
    }
  }

  ~OpenSlRunnerTemplate() {}

  void StartPlayRecord() {
    output_.StartPlayout();
    input_.StartRecording();
  }

  void StopPlayRecord() {
    // There are large enough buffers to compensate for recording and playing
    // jitter such that the timing of stopping playing or recording should not
    // result in over or underrun.
    input_.StopRecording();
    output_.StopPlayout();
    audio_buffer_.ClearBuffer();
  }

  void RegisterApplicationContext(
      JNIEnv* env,
      jobject obj,
      jobject context) {
    OutputType::SetAndroidAudioDeviceObjects(env, obj, context);
    InputType::SetAndroidAudioDeviceObjects(env, obj, context);
  }

 private:
  OutputType output_;
  InputType input_;
  FakeAudioDeviceBuffer audio_buffer_;
};

class OpenSlRunner
    : public OpenSlRunnerTemplate<OpenSlesInput, OpenSlesOutput> {
 public:
  // Global class implementing native code.
  static OpenSlRunner* g_runner;

  OpenSlRunner() {}
  virtual ~OpenSlRunner() {}

  static JNIEXPORT void JNICALL RegisterApplicationContext(
      JNIEnv* env,
      jobject obj,
      jobject context) {
    assert(!g_runner);  // Should only be called once.
    g_runner = new OpenSlRunner();
  }

  static JNIEXPORT void JNICALL Start(JNIEnv * env, jobject) {
    g_runner->StartPlayRecord();
  }

  static JNIEXPORT void JNICALL Stop(JNIEnv * env, jobject) {
    g_runner->StopPlayRecord();
  }
};

OpenSlRunner* OpenSlRunner::g_runner = NULL;

}  // namespace webrtc

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
  // Only called once.
  assert(!g_vm);
  JNIEnv* env;
  if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
    return -1;
  }

  jclass local_osr = env->FindClass("org/webrtc/app/OpenSlRunner");
  assert(local_osr != NULL);
  g_osr = static_cast<jclass>(env->NewGlobalRef(local_osr));
  JNINativeMethod nativeFunctions[] = {
    {"RegisterApplicationContext", "(Landroid/content/Context;)V",
     reinterpret_cast<void*>(
         &webrtc::OpenSlRunner::RegisterApplicationContext)},
    {"Start", "()V", reinterpret_cast<void*>(&webrtc::OpenSlRunner::Start)},
    {"Stop",  "()V", reinterpret_cast<void*>(&webrtc::OpenSlRunner::Stop)}
  };
  int ret_val = env->RegisterNatives(g_osr, nativeFunctions, 3);
  if (ret_val != 0) {
    assert(false);
  }
  g_vm = vm;
  return JNI_VERSION_1_6;
}
<commit_msg>Android, OpenSlDemo: fixes issue where app would crash as soon as the application is started.<commit_after>/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>
#include <jni.h>

#include "webrtc/modules/audio_device/android/audio_device_template.h"
#include "webrtc/modules/audio_device/android/audio_record_jni.h"
#include "webrtc/modules/audio_device/android/audio_track_jni.h"
#include "webrtc/modules/audio_device/android/opensles_input.h"
#include "webrtc/modules/audio_device/android/opensles_output.h"
#include "webrtc/modules/audio_device/android/test/fake_audio_device_buffer.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"

// Java globals
static JavaVM* g_vm = NULL;
static jclass g_osr = NULL;

namespace webrtc {

template <class InputType, class OutputType>
class OpenSlRunnerTemplate {
 public:
  OpenSlRunnerTemplate()
      : output_(0),
        input_(0, &output_) {
    output_.AttachAudioBuffer(&audio_buffer_);
    if (output_.Init() != 0) {
      assert(false);
    }
    if (output_.InitPlayout() != 0) {
      assert(false);
    }
    input_.AttachAudioBuffer(&audio_buffer_);
    if (input_.Init() != 0) {
      assert(false);
    }
    if (input_.InitRecording() != 0) {
      assert(false);
    }
  }

  ~OpenSlRunnerTemplate() {}

  void StartPlayRecord() {
    output_.StartPlayout();
    input_.StartRecording();
  }

  void StopPlayRecord() {
    // There are large enough buffers to compensate for recording and playing
    // jitter such that the timing of stopping playing or recording should not
    // result in over or underrun.
    input_.StopRecording();
    output_.StopPlayout();
    audio_buffer_.ClearBuffer();
  }

 private:
  OutputType output_;
  InputType input_;
  FakeAudioDeviceBuffer audio_buffer_;
};

class OpenSlRunner
    : public OpenSlRunnerTemplate<OpenSlesInput, OpenSlesOutput> {
 public:
  // Global class implementing native code.
  static OpenSlRunner* g_runner;

  OpenSlRunner() {}
  virtual ~OpenSlRunner() {}

  static JNIEXPORT void JNICALL RegisterApplicationContext(
      JNIEnv* env,
      jobject obj,
      jobject context) {
    assert(!g_runner);  // Should only be called once.
    // Register the application context in the superclass to avoid having to
    // qualify the template instantiation again.
    OpenSlesInput::SetAndroidAudioDeviceObjects(g_vm, env, context);
    OpenSlesOutput::SetAndroidAudioDeviceObjects(g_vm, env, context);
    g_runner = new OpenSlRunner();
  }

  static JNIEXPORT void JNICALL Start(JNIEnv * env, jobject) {
    g_runner->StartPlayRecord();
  }

  static JNIEXPORT void JNICALL Stop(JNIEnv * env, jobject) {
    g_runner->StopPlayRecord();
  }
};

OpenSlRunner* OpenSlRunner::g_runner = NULL;

}  // namespace webrtc

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
  // Only called once.
  assert(!g_vm);
  JNIEnv* env;
  if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
    return -1;
  }

  jclass local_osr = env->FindClass("org/webrtc/app/OpenSlRunner");
  assert(local_osr != NULL);
  g_osr = static_cast<jclass>(env->NewGlobalRef(local_osr));
  JNINativeMethod nativeFunctions[] = {
    {"RegisterApplicationContext", "(Landroid/content/Context;)V",
     reinterpret_cast<void*>(
         &webrtc::OpenSlRunner::RegisterApplicationContext)},
    {"Start", "()V", reinterpret_cast<void*>(&webrtc::OpenSlRunner::Start)},
    {"Stop",  "()V", reinterpret_cast<void*>(&webrtc::OpenSlRunner::Stop)}
  };
  int ret_val = env->RegisterNatives(g_osr, nativeFunctions, 3);
  if (ret_val != 0) {
    assert(false);
  }
  g_vm = vm;
  return JNI_VERSION_1_6;
}
<|endoftext|>


<commit_before>#include <sstream>

#include "StorageFlattening.h"
#include "IRMutator.h"
#include "IROperator.h"
#include "Scope.h"
#include "Bounds.h"
#include "Parameter.h"

namespace Halide {
namespace Internal {

using std::ostringstream;
using std::string;
using std::vector;
using std::map;
using std::pair;
using std::set;

namespace {

class FlattenDimensions : public IRMutator {
public:
    FlattenDimensions(const map<string, pair<Function, int>> &e, const Target &t)
        : env(e), target(t) {}
    Scope<int> scope;
private:
    const map<string, pair<Function, int>> &env;
    const Target ⌖
    Scope<int> realizations;

    Expr flatten_args(const string &name, const vector<Expr> &args) {
        bool internal = realizations.contains(name);
        Expr idx = target.has_feature(Target::LargeBuffers) ? make_zero(Int(64)) : 0;
        vector<Expr> mins(args.size()), strides(args.size());

        for (size_t i = 0; i < args.size(); i++) {
            string dim = std::to_string(i);
            string stride_name = name + ".stride." + dim;
            string min_name = name + ".min." + dim;
            string stride_name_constrained = stride_name + ".constrained";
            string min_name_constrained = min_name + ".constrained";
            if (scope.contains(stride_name_constrained)) {
                stride_name = stride_name_constrained;
            }
            if (scope.contains(min_name_constrained)) {
                min_name = min_name_constrained;
            }
            strides[i] = Variable::make(Int(32), stride_name);
            mins[i] = Variable::make(Int(32), min_name);
        }

        if (internal) {
            // f(x, y) -> f[(x-xmin)*xstride + (y-ymin)*ystride] This
            // strategy makes sense when we expect x to cancel with
            // something in xmin.  We use this for internal allocations
            for (size_t i = 0; i < args.size(); i++) {
                if (target.has_feature(Target::LargeBuffers)) {
                    idx += cast<int64_t>(args[i] - mins[i]) * cast<int64_t>(strides[i]);
                } else {
                    idx += (args[i] - mins[i]) * strides[i];
                }
            }
        } else {
            // f(x, y) -> f[x*stride + y*ystride - (xstride*xmin +
            // ystride*ymin)]. The idea here is that the last term
            // will be pulled outside the inner loop. We use this for
            // external buffers, where the mins and strides are likely
            // to be symbolic
            Expr base = target.has_feature(Target::LargeBuffers) ? make_zero(Int(64)) : 0;
            for (size_t i = 0; i < args.size(); i++) {
                if (target.has_feature(Target::LargeBuffers)) {
                    idx += cast<int64_t>(args[i]) * cast<int64_t>(strides[i]);
                    base += cast<int64_t>(mins[i]) * cast<int64_t>(strides[i]);
                } else {
                    idx += args[i] * strides[i];
                    base += mins[i] * strides[i];
                }
            }
            idx -= base;
        }

        return idx;
    }

    using IRMutator::visit;

    void visit(const Realize *op) {
        realizations.push(op->name, 0);

        Stmt body = mutate(op->body);

        // Compute the size
        std::vector<Expr> extents;
        for (size_t i = 0; i < op->bounds.size(); i++) {
            extents.push_back(op->bounds[i].extent);
            extents[i] = mutate(extents[i]);
        }
        Expr condition = mutate(op->condition);

        realizations.pop(op->name);

        vector<int> storage_permutation;
        {
            auto iter = env.find(op->name);
            Function f = iter->second.first;
            internal_assert(iter != env.end()) << "Realize node refers to function not in environment.\n";
            const vector<StorageDim> &storage_dims = f.schedule().storage_dims();
            const vector<string> &args = f.args();
            for (size_t i = 0; i < storage_dims.size(); i++) {
                for (size_t j = 0; j < args.size(); j++) {
                    if (args[j] == storage_dims[i].var) {
                        storage_permutation.push_back((int)j);
                        Expr alignment = storage_dims[i].alignment;
                        if (alignment.defined()) {
                            extents[j] = ((extents[j] + alignment - 1)/alignment)*alignment;
                        }
                    }
                }
                internal_assert(storage_permutation.size() == i+1);
            }
        }

        internal_assert(storage_permutation.size() == op->bounds.size());

        stmt = body;
        internal_assert(op->types.size() == 1);

        // Make the names for the mins, extents, and strides
        int dims = op->bounds.size();
        vector<string> min_name(dims), extent_name(dims), stride_name(dims);
        for (int i = 0; i < dims; i++) {
            string d = std::to_string(i);
            min_name[i] = op->name + ".min." + d;
            stride_name[i] = op->name + ".stride." + d;
            extent_name[i] = op->name + ".extent." + d;
        }
        vector<Expr> min_var(dims), extent_var(dims), stride_var(dims);
        for (int i = 0; i < dims; i++) {
            min_var[i] = Variable::make(Int(32), min_name[i]);
            extent_var[i] = Variable::make(Int(32), extent_name[i]);
            stride_var[i] = Variable::make(Int(32), stride_name[i]);
        }

        // Create a buffer_t object for this allocation.
        if (dims <= 4) {
            BufferBuilder builder;
            Expr first_elem = Load::make(op->types[0], op->name, 0, Buffer<>(), Parameter(),
                                         const_true(op->types[0].lanes()));
            builder.host = Call::make(Handle(), Call::address_of, {first_elem}, Call::PureIntrinsic);
            builder.type = op->types[0];
            builder.dimensions = dims;
            for (int i = 0; i < dims; i++) {
                builder.mins.push_back(min_var[i]);
                builder.extents.push_back(extent_var[i]);
                builder.strides.push_back(stride_var[i]);
            }
            stmt = LetStmt::make(op->name + ".buffer", builder.build(), stmt);
        }

        // Make the allocation node
        stmt = Allocate::make(op->name, op->types[0], extents, condition, stmt);

        // Compute the strides
        for (int i = (int)op->bounds.size()-1; i > 0; i--) {
            int prev_j = storage_permutation[i-1];
            int j = storage_permutation[i];
            Expr stride = stride_var[prev_j] * extent_var[prev_j];
            stmt = LetStmt::make(stride_name[j], stride, stmt);
        }

        // Innermost stride is one
        if (dims > 0) {
            int innermost = storage_permutation.empty() ? 0 : storage_permutation[0];
            stmt = LetStmt::make(stride_name[innermost], 1, stmt);
        }

        // Assign the mins and extents stored
        for (size_t i = op->bounds.size(); i > 0; i--) {
            stmt = LetStmt::make(min_name[i-1], op->bounds[i-1].min, stmt);
            stmt = LetStmt::make(extent_name[i-1], extents[i-1], stmt);
        }
    }

    void visit(const Provide *op) {
        internal_assert(op->values.size() == 1);

        Expr idx = mutate(flatten_args(op->name, op->args));
        Expr value = mutate(op->values[0]);
        stmt = Store::make(op->name, value, idx, Parameter(), const_true(value.type().lanes()));
    }

    void visit(const Call *op) {
        if (op->call_type == Call::Halide ||
            op->call_type == Call::Image) {
            internal_assert(op->value_index == 0);
            Expr idx = mutate(flatten_args(op->name, op->args));
            expr = Load::make(op->type, op->name, idx, op->image, op->param,
                              const_true(op->type.lanes()));
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const LetStmt *let) {
        // Discover constrained versions of things.
        bool constrained_version_exists = ends_with(let->name, ".constrained");
        if (constrained_version_exists) {
            scope.push(let->name, 0);
        }

        IRMutator::visit(let);

        if (constrained_version_exists) {
            scope.pop(let->name);
        }
    }
};

// Realizations, stores, and loads must all be on types that are
// multiples of 8-bits. This really only affects bools
class PromoteToMemoryType : public IRMutator {
    using IRMutator::visit;

    Type upgrade(Type t) {
        return t.with_bits(((t.bits() + 7)/8)*8);
    }

    void visit(const Call *op) {
        if (op->is_intrinsic(Call::address_of)) {
            Expr load = mutate(op->args[0]);
            if (const Cast *cast = load.as<Cast>()) {
                load = cast->value;
            }
            expr = Call::make(op->type, op->name, {load}, op->call_type);
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Load *op) {
        Type t = upgrade(op->type);
        if (t != op->type) {
            expr = Cast::make(op->type, Load::make(t, op->name, mutate(op->index),
                                                   op->image, op->param, mutate(op->predicate)));
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Store *op) {
        Type t = upgrade(op->value.type());
        if (t != op->value.type()) {
            stmt = Store::make(op->name, Cast::make(t, mutate(op->value)), mutate(op->index),
                                                    op->param, mutate(op->predicate));
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Allocate *op) {
        Type t = upgrade(op->type);
        if (t != op->type) {
            vector<Expr> extents;
            for (Expr e : op->extents) {
                extents.push_back(mutate(e));
            }
            stmt = Allocate::make(op->name, t, extents,
                                  mutate(op->condition), mutate(op->body),
                                  mutate(op->new_expr), op->free_function);
        } else {
            IRMutator::visit(op);
        }
    }
};

// Connect Store nodes to their output buffers
class ConnectOutputBuffers : public IRMutator {
    using IRMutator::visit;

    void visit(const Store *op) {
        Parameter output_buf;
        auto it = env.find(op->name);
        if (it != env.end()) {
            const Function &f = it->second.first;
            int idx = it->second.second;

            // We only want to do this for actual pipeline outputs,
            // even though every Function has an output buffer. Any
            // constraints you set on the output buffer of a Func that
            // isn't actually an output is ignored. This is a language
            // wart.
            if (outputs.count(f.name())) {
                output_buf = f.output_buffers()[idx];
            }
        }

        if (output_buf.defined()) {
            stmt = Store::make(op->name, op->value, op->index, output_buf, const_true());
        } else {
            stmt = op;
        }
    }

    const map<string, pair<Function, int>> &env;
    set<string> outputs;

public:
    ConnectOutputBuffers(const std::map<string, pair<Function, int>> &e,
                         const vector<Function> &o) : env(e) {
        for (auto &f : o) {
            outputs.insert(f.name());
        }
    }
};

}  // namespace

Stmt storage_flattening(Stmt s,
                        const vector<Function> &outputs,
                        const map<string, Function> &env,
                        const Target &target) {
    // Make an environment that makes it easier to figure out which
    // Function corresponds to a tuple component. foo.0, foo.1, foo.2,
    // all point to the function foo.
    map<string, pair<Function, int>> tuple_env;
    for (auto p : env) {
        if (p.second.outputs() > 1) {
            for (int i = 0; i < p.second.outputs(); i++) {
                tuple_env[p.first + "." + std::to_string(i)] = {p.second, i};
            }
        } else {
            tuple_env[p.first] = {p.second, 0};
        }
    }

    s = FlattenDimensions(tuple_env, target).mutate(s);
    s = PromoteToMemoryType().mutate(s);
    s = ConnectOutputBuffers(tuple_env, outputs).mutate(s);
    return s;
}

}
}
<commit_msg>Fix .min/.stride symbols not being connected to Param<commit_after>#include <sstream>

#include "StorageFlattening.h"
#include "IRMutator.h"
#include "IROperator.h"
#include "Scope.h"
#include "Bounds.h"
#include "Parameter.h"

namespace Halide {
namespace Internal {

using std::ostringstream;
using std::string;
using std::vector;
using std::map;
using std::pair;
using std::set;

namespace {

class FlattenDimensions : public IRMutator {
public:
    FlattenDimensions(const map<string, pair<Function, int>> &e,
                      const vector<Function> &o,
                      const Target &t)
        : env(e), target(t) {
        for (auto &f : o) {
            outputs.insert(f.name());
        }
    }
    Scope<int> scope;
private:
    const map<string, pair<Function, int>> &env;
    set<string> outputs;
    const Target ⌖
    Scope<int> realizations;

    Expr flatten_args(const string &name, const vector<Expr> &args,
                      const Buffer<> &buf, const Parameter &param) {
        bool internal = realizations.contains(name);
        Expr idx = target.has_feature(Target::LargeBuffers) ? make_zero(Int(64)) : 0;
        vector<Expr> mins(args.size()), strides(args.size());

        ReductionDomain rdom;
        for (size_t i = 0; i < args.size(); i++) {
            string dim = std::to_string(i);
            string stride_name = name + ".stride." + dim;
            string min_name = name + ".min." + dim;
            string stride_name_constrained = stride_name + ".constrained";
            string min_name_constrained = min_name + ".constrained";
            if (scope.contains(stride_name_constrained)) {
                stride_name = stride_name_constrained;
            }
            if (scope.contains(min_name_constrained)) {
                min_name = min_name_constrained;
            }
            strides[i] = Variable::make(Int(32), stride_name, buf, param, rdom);
            mins[i] = Variable::make(Int(32), min_name, buf, param, rdom);
        }

        if (internal) {
            // f(x, y) -> f[(x-xmin)*xstride + (y-ymin)*ystride] This
            // strategy makes sense when we expect x to cancel with
            // something in xmin.  We use this for internal allocations
            for (size_t i = 0; i < args.size(); i++) {
                if (target.has_feature(Target::LargeBuffers)) {
                    idx += cast<int64_t>(args[i] - mins[i]) * cast<int64_t>(strides[i]);
                } else {
                    idx += (args[i] - mins[i]) * strides[i];
                }
            }
        } else {
            // f(x, y) -> f[x*stride + y*ystride - (xstride*xmin +
            // ystride*ymin)]. The idea here is that the last term
            // will be pulled outside the inner loop. We use this for
            // external buffers, where the mins and strides are likely
            // to be symbolic
            Expr base = target.has_feature(Target::LargeBuffers) ? make_zero(Int(64)) : 0;
            for (size_t i = 0; i < args.size(); i++) {
                if (target.has_feature(Target::LargeBuffers)) {
                    idx += cast<int64_t>(args[i]) * cast<int64_t>(strides[i]);
                    base += cast<int64_t>(mins[i]) * cast<int64_t>(strides[i]);
                } else {
                    idx += args[i] * strides[i];
                    base += mins[i] * strides[i];
                }
            }
            idx -= base;
        }

        return idx;
    }

    using IRMutator::visit;

    void visit(const Realize *op) {
        realizations.push(op->name, 0);

        Stmt body = mutate(op->body);

        // Compute the size
        std::vector<Expr> extents;
        for (size_t i = 0; i < op->bounds.size(); i++) {
            extents.push_back(op->bounds[i].extent);
            extents[i] = mutate(extents[i]);
        }
        Expr condition = mutate(op->condition);

        realizations.pop(op->name);

        vector<int> storage_permutation;
        {
            auto iter = env.find(op->name);
            Function f = iter->second.first;
            internal_assert(iter != env.end()) << "Realize node refers to function not in environment.\n";
            const vector<StorageDim> &storage_dims = f.schedule().storage_dims();
            const vector<string> &args = f.args();
            for (size_t i = 0; i < storage_dims.size(); i++) {
                for (size_t j = 0; j < args.size(); j++) {
                    if (args[j] == storage_dims[i].var) {
                        storage_permutation.push_back((int)j);
                        Expr alignment = storage_dims[i].alignment;
                        if (alignment.defined()) {
                            extents[j] = ((extents[j] + alignment - 1)/alignment)*alignment;
                        }
                    }
                }
                internal_assert(storage_permutation.size() == i+1);
            }
        }

        internal_assert(storage_permutation.size() == op->bounds.size());

        stmt = body;
        internal_assert(op->types.size() == 1);

        // Make the names for the mins, extents, and strides
        int dims = op->bounds.size();
        vector<string> min_name(dims), extent_name(dims), stride_name(dims);
        for (int i = 0; i < dims; i++) {
            string d = std::to_string(i);
            min_name[i] = op->name + ".min." + d;
            stride_name[i] = op->name + ".stride." + d;
            extent_name[i] = op->name + ".extent." + d;
        }
        vector<Expr> min_var(dims), extent_var(dims), stride_var(dims);
        for (int i = 0; i < dims; i++) {
            min_var[i] = Variable::make(Int(32), min_name[i]);
            extent_var[i] = Variable::make(Int(32), extent_name[i]);
            stride_var[i] = Variable::make(Int(32), stride_name[i]);
        }

        // Create a buffer_t object for this allocation.
        if (dims <= 4) {
            BufferBuilder builder;
            Expr first_elem = Load::make(op->types[0], op->name, 0, Buffer<>(), Parameter(),
                                         const_true(op->types[0].lanes()));
            builder.host = Call::make(Handle(), Call::address_of, {first_elem}, Call::PureIntrinsic);
            builder.type = op->types[0];
            builder.dimensions = dims;
            for (int i = 0; i < dims; i++) {
                builder.mins.push_back(min_var[i]);
                builder.extents.push_back(extent_var[i]);
                builder.strides.push_back(stride_var[i]);
            }
            stmt = LetStmt::make(op->name + ".buffer", builder.build(), stmt);
        }

        // Make the allocation node
        stmt = Allocate::make(op->name, op->types[0], extents, condition, stmt);

        // Compute the strides
        for (int i = (int)op->bounds.size()-1; i > 0; i--) {
            int prev_j = storage_permutation[i-1];
            int j = storage_permutation[i];
            Expr stride = stride_var[prev_j] * extent_var[prev_j];
            stmt = LetStmt::make(stride_name[j], stride, stmt);
        }

        // Innermost stride is one
        if (dims > 0) {
            int innermost = storage_permutation.empty() ? 0 : storage_permutation[0];
            stmt = LetStmt::make(stride_name[innermost], 1, stmt);
        }

        // Assign the mins and extents stored
        for (size_t i = op->bounds.size(); i > 0; i--) {
            stmt = LetStmt::make(min_name[i-1], op->bounds[i-1].min, stmt);
            stmt = LetStmt::make(extent_name[i-1], extents[i-1], stmt);
        }
    }

    void visit(const Provide *op) {
        internal_assert(op->values.size() == 1);

        Parameter output_buf;
        auto it = env.find(op->name);
        if (it != env.end()) {
            const Function &f = it->second.first;
            int idx = it->second.second;

            // We only want to do this for actual pipeline outputs,
            // even though every Function has an output buffer. Any
            // constraints you set on the output buffer of a Func that
            // isn't actually an output is ignored. This is a language
            // wart.
            if (outputs.count(f.name())) {
                output_buf = f.output_buffers()[idx];
            }
        }

        Expr idx = mutate(flatten_args(op->name, op->args, Buffer<>(), output_buf));
        Expr value = mutate(op->values[0]);
        stmt = Store::make(op->name, value, idx, output_buf, const_true(value.type().lanes()));
    }

    void visit(const Call *op) {
        if (op->call_type == Call::Halide ||
            op->call_type == Call::Image) {
            internal_assert(op->value_index == 0);
            Expr idx = mutate(flatten_args(op->name, op->args, op->image, op->param));
            expr = Load::make(op->type, op->name, idx, op->image, op->param,
                              const_true(op->type.lanes()));
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const LetStmt *let) {
        // Discover constrained versions of things.
        bool constrained_version_exists = ends_with(let->name, ".constrained");
        if (constrained_version_exists) {
            scope.push(let->name, 0);
        }

        IRMutator::visit(let);

        if (constrained_version_exists) {
            scope.pop(let->name);
        }
    }
};

// Realizations, stores, and loads must all be on types that are
// multiples of 8-bits. This really only affects bools
class PromoteToMemoryType : public IRMutator {
    using IRMutator::visit;

    Type upgrade(Type t) {
        return t.with_bits(((t.bits() + 7)/8)*8);
    }

    void visit(const Call *op) {
        if (op->is_intrinsic(Call::address_of)) {
            Expr load = mutate(op->args[0]);
            if (const Cast *cast = load.as<Cast>()) {
                load = cast->value;
            }
            expr = Call::make(op->type, op->name, {load}, op->call_type);
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Load *op) {
        Type t = upgrade(op->type);
        if (t != op->type) {
            expr = Cast::make(op->type, Load::make(t, op->name, mutate(op->index),
                                                   op->image, op->param, mutate(op->predicate)));
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Store *op) {
        Type t = upgrade(op->value.type());
        if (t != op->value.type()) {
            stmt = Store::make(op->name, Cast::make(t, mutate(op->value)), mutate(op->index),
                                                    op->param, mutate(op->predicate));
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Allocate *op) {
        Type t = upgrade(op->type);
        if (t != op->type) {
            vector<Expr> extents;
            for (Expr e : op->extents) {
                extents.push_back(mutate(e));
            }
            stmt = Allocate::make(op->name, t, extents,
                                  mutate(op->condition), mutate(op->body),
                                  mutate(op->new_expr), op->free_function);
        } else {
            IRMutator::visit(op);
        }
    }
};

}  // namespace

Stmt storage_flattening(Stmt s,
                        const vector<Function> &outputs,
                        const map<string, Function> &env,
                        const Target &target) {
    // Make an environment that makes it easier to figure out which
    // Function corresponds to a tuple component. foo.0, foo.1, foo.2,
    // all point to the function foo.
    map<string, pair<Function, int>> tuple_env;
    for (auto p : env) {
        if (p.second.outputs() > 1) {
            for (int i = 0; i < p.second.outputs(); i++) {
                tuple_env[p.first + "." + std::to_string(i)] = {p.second, i};
            }
        } else {
            tuple_env[p.first] = {p.second, 0};
        }
    }

    s = FlattenDimensions(tuple_env, outputs, target).mutate(s);
    s = PromoteToMemoryType().mutate(s);
    return s;
}

}
}
<|endoftext|>


<commit_before>#ifdef LINUX

#include "Os.h"
#include <vector>
#include <string>
#include <set>
#include <map>
#include <algorithm>
#include <cstdio>

#include <sys/time.h>

#include <X11/Xlib.h>
#include <GL/glx.h>

using namespace std;

Display *display = NULL;
int screen = 0;
XIM xim = NULL;

struct OsWindowData {
  OsWindowData() { window = NULL; }
  ~OsWindowData() {
    glXDestroyContext(display, context);
    XDestroyIC(inputcontext);
    XDestroyWindow(display, window);
  }

  Window window;
  GLXContext context;
  XIC inputcontext;
};

void Os::Init() {
  display = XOpenDisplay(NULL);
  ASSERT(display);

  screen = DefaultScreen(display);

  xim = XOpenIM(display, NULL, NULL, NULL);
  ASSERT(xim);
}
void Os::ShutDown() {
  XCloseIM(xim);
  XCloseDisplay(display);
}

vector<Os::KeyEvent> events;

Bool EventTester(Display *display, XEvent *event, XPointer arg) {
  return true; // hurrr
}
void Os::Think() { } // we don't actually do anything here
void Os::WindowThink(OsWindowData* data) {
  XEvent event;
  while(XCheckIfEvent(display, &event, &EventTester, NULL)) {
    LOGF("Event incoming!\n");
  }
}

OsWindowData* Os::CreateWindow(const string& title, int x, int y, int width, int height, bool full_screen, short stencil_bits, const Image* icon, bool is_resizable) {
  OsWindowData *nw = new OsWindowData();

  // this is bad
  if(x == -1) x = 100;
  if(y == -1) y = 100;

  // I think there's a way to specify more of this but I'll be damned if I can find it
  XVisualInfo vinfo_template;
  vinfo_template.screen = screen;
  int vinfo_ct;
  XVisualInfo *visualinfo = XGetVisualInfo(display, VisualScreenMask, &vinfo_template, &vinfo_ct);
  ASSERT(visualinfo);
  ASSERT(vinfo_ct);

  XVisualInfo vinfo;
  bool found = false;
  for(int i = 0; i < vinfo_ct; i++) {
    int use_gl, rgba, doublebuffer, red_size, green_size, blue_size, alpha_size;
    glXGetConfig(display, &visualinfo[i], GLX_USE_GL, &use_gl);
    glXGetConfig(display, &visualinfo[i], GLX_RGBA, &rgba);
    glXGetConfig(display, &visualinfo[i], GLX_DOUBLEBUFFER, &doublebuffer);
    glXGetConfig(display, &visualinfo[i], GLX_RED_SIZE, &red_size);
    glXGetConfig(display, &visualinfo[i], GLX_GREEN_SIZE, &green_size);
    glXGetConfig(display, &visualinfo[i], GLX_BLUE_SIZE, &blue_size);
    glXGetConfig(display, &visualinfo[i], GLX_ALPHA_SIZE, &alpha_size);
    //LOGF("%d %d %d %d %d %d %d", use_gl, rgba, doublebuffer, red_size, green_size, blue_size, alpha_size);

    if(use_gl && rgba && doublebuffer && red_size == 8 && green_size == 8 && blue_size == 8 && alpha_size == 8) {
      LOGF("Found something!");
      found = true;
      vinfo = visualinfo[i]; // I'm just going to hope the rest of the values are appropriate, because, really, who knows
      break;
    }
  }

  ASSERT(found);

  nw->context = glXCreateContext(display, &vinfo, NULL, True);
  ASSERT(nw->context);

  nw->window = XCreateWindow(display, RootWindow(display, screen), x, y, width, height, 0, vinfo.depth, InputOutput, vinfo.visual, 0, NULL); // I don't know if I need anything further here

  SetTitle(nw, title);

  // I think in here is where we're meant to set window styles and stuff

  nw->inputcontext = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, nw->window, XNFocusWindow, nw->window, NULL);
  ASSERT(nw->inputcontext);

  XFree(visualinfo);

  XMapWindow(display, nw->window);

  SetCurrentContext(nw);

  return nw;
}

void Os::SetCurrentContext(OsWindowData* data) {
  glXMakeCurrent(display, data->window, data->context);
}

// Destroys a window that is completely or partially created.
void Os::DestroyWindow(OsWindowData* data) {
  delete data;
}

bool Os::IsWindowMinimized(const OsWindowData* data) {
  return false;
}

void Os::GetWindowFocusState(OsWindowData* data, bool* is_in_focus, bool* focus_changed) {
  *is_in_focus = true;
  *focus_changed = false;
}

void Os::GetWindowPosition(const OsWindowData* data, int* x, int* y) {
  XWindowAttributes attrs;
  XGetWindowAttributes(display, data->window, &attrs);
  *x = attrs.x;
  *y = attrs.y;
}

void Os::GetWindowSize(const OsWindowData* data, int* width, int* height) {
  XWindowAttributes attrs;
  XGetWindowAttributes(display, data->window, &attrs);
  *width  = attrs.width;
  *height = attrs.height;
}

void Os::SetTitle(OsWindowData* data, const string& title) {
  XStoreName(display, data->window, title.c_str());
}

void Os::SetIcon(OsWindowData *window, const Image *icon) {
  fprintf(stderr, "Os::SetIcon(%p, %p)\n", window, icon); // TBI
}

void Os::SetWindowSize(OsWindowData *window, int width, int height) {
  fprintf(stderr, "Os::SetWindowSize(%p, %d, %d)\n", window, width, height); // TBI
}

// Input functions
// ===============

// See Os.h

vector<Os::KeyEvent> Os::GetInputEvents(OsWindowData *window) {
  vector<Os::KeyEvent> ret; // weeeeeeeeeeee
  ret.swap(events);

  Window root, child;
  int x, y, winx, winy;
  unsigned int mask;
  XQueryPointer(display, window->window, &root, &child, &x, &y, &winx, &winy, &mask);

  ret.push_back(Os::KeyEvent(GetTime(), x, y, mask & (1 << 4), mask & LockMask));

  return ret;
}

void Os::SetMousePosition(int x, int y) { // TBI
}

void Os::ShowMouseCursor(bool is_shown) { // TBI
}

void Os::RefreshJoysticks(OsWindowData *window) { // TBI
}

int Os::GetNumJoysticks(OsWindowData *window) { // TBI
  return 0;
}

// Threading functions
// ===================

#include <pthread.h>

void Os::StartThread(void(*thread_function)(void*), void* data) {
  pthread_t thread;
  if (pthread_create(&thread, NULL, (void*(*)(void*))thread_function, data) != 0) {
    printf("Error forking thread\n");
  }
}

struct OsMutex {
  pthread_mutex_t mutex;
};

OsMutex* Os::NewMutex() {
  OsMutex* mutex = new OsMutex;
  pthread_mutex_init(&mutex->mutex, NULL);
  return mutex;
}

void Os::DeleteMutex(OsMutex* mutex) {
  pthread_mutex_destroy(&mutex->mutex);
  delete mutex;
}

void Os::AcquireMutex(OsMutex* mutex) {
  pthread_mutex_lock(&mutex->mutex);
}

void Os::ReleaseMutex(OsMutex* mutex) {
  pthread_mutex_unlock(&mutex->mutex);
}

// Miscellaneous functions
// =======================

void Os::MessageBox(const string& title, const string& message) { // TBI
  fprintf(stderr,"MessageBox [%s]: [%s]\n", title.c_str(), message.c_str());
}

vector<pair<int, int> > Os::GetFullScreenModes() { // TBI
  return vector<pair<int, int> >(1,pair<int, int>(640,480));
}

void Os::Sleep(int t) {
  usleep(t*1000);
}

int Os::GetTime() {
  return GetTimeMicro() / 1000;
}
long long Os::GetTimeMicro() {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return (long long)tv.tv_sec * 1000000 + tv.tv_usec;
}

void Os::SwapBuffers(OsWindowData* data) {
  glXSwapBuffers(display, data->window);
}

int Os::GetRefreshRate() { // TBI
  //fprintf(stderr,"OS::GetRefreshRate()\n");
  return 60;
}

void Os::EnableVSync(bool is_enable) { // TBI
  fprintf(stderr,"OS::EnableVSync(%d)\n", is_enable);
}

vector<string> Os::ListFiles(const string &directory) { // TBI
  fprintf(stderr,"OS::ListFiles(%s)\n", directory.c_str());
  return vector<string>();
}

vector<string> Os::ListSubdirectories(const string &directory) { // TBI
  fprintf(stderr,"OS::ListSubdirectories(%s)\n", directory.c_str());
  return vector<string>();
}

#endif // LINUX

<commit_msg>things mostly work<commit_after>#ifdef LINUX

#include "Os.h"
#include <vector>
#include <string>
#include <set>
#include <map>
#include <algorithm>
#include <cstdio>

#include <sys/time.h>

#include <X11/Xlib.h>
#include <GL/glx.h>

using namespace std;

Display *display = NULL;
int screen = 0;
XIM xim = NULL;

static long long gtm() {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return (long long)tv.tv_sec * 1000000 + tv.tv_usec;
}
static int gt() {
  return gtm() / 1000;
}

struct OsWindowData {
  OsWindowData() { window = NULL; }
  ~OsWindowData() {
    glXDestroyContext(display, context);
    XDestroyIC(inputcontext);
    XDestroyWindow(display, window);
  }

  Window window;
  GLXContext context;
  XIC inputcontext;
};

void Os::Init() {
  display = XOpenDisplay(NULL);
  ASSERT(display);

  screen = DefaultScreen(display);

  xim = XOpenIM(display, NULL, NULL, NULL);
  ASSERT(xim);
}
void Os::ShutDown() {
  XCloseIM(xim);
  XCloseDisplay(display);
}

vector<Os::KeyEvent> events;
static bool SynthKey(const KeySym &sym, bool pushed, const XEvent &event, Window window, Os::KeyEvent *ev) {
  // mostly ignored
  Window root, child;
  int x, y, winx, winy;
  unsigned int mask;
  XQueryPointer(display, window, &root, &child, &x, &y, &winx, &winy, &mask);

  KeySym throwaway_lower, key;
  XConvertCase(sym, &throwaway_lower, &key);

  GlopKey ki = 0;
  switch(key) {
    case XK_A: ki = tolower('A'); break;
    case XK_B: ki = tolower('B'); break;
    case XK_C: ki = tolower('C'); break;
    case XK_D: ki = tolower('D'); break;
    case XK_E: ki = tolower('E'); break;
    case XK_F: ki = tolower('F'); break;
    case XK_G: ki = tolower('G'); break;
    case XK_H: ki = tolower('H'); break;
    case XK_I: ki = tolower('I'); break;
    case XK_J: ki = tolower('J'); break;
    case XK_K: ki = tolower('K'); break;
    case XK_L: ki = tolower('L'); break;
    case XK_M: ki = tolower('M'); break;
    case XK_N: ki = tolower('N'); break;
    case XK_O: ki = tolower('O'); break;
    case XK_P: ki = tolower('P'); break;
    case XK_Q: ki = tolower('Q'); break;
    case XK_R: ki = tolower('R'); break;
    case XK_S: ki = tolower('S'); break;
    case XK_T: ki = tolower('T'); break;
    case XK_U: ki = tolower('U'); break;
    case XK_V: ki = tolower('V'); break;
    case XK_W: ki = tolower('W'); break;
    case XK_X: ki = tolower('X'); break;
    case XK_Y: ki = tolower('Y'); break;
    case XK_Z: ki = tolower('Z'); break;

    case XK_0: ki = '0'; break;
    case XK_1: ki = '1'; break;
    case XK_2: ki = '2'; break;
    case XK_3: ki = '3'; break;
    case XK_4: ki = '4'; break;
    case XK_5: ki = '5'; break;
    case XK_6: ki = '6'; break;
    case XK_7: ki = '7'; break;
    case XK_8: ki = '8'; break;
    case XK_9: ki = '9'; break;

    case XK_F1: ki = kKeyF1; break;
    case XK_F2: ki = kKeyF2; break;
    case XK_F3: ki = kKeyF3; break;
    case XK_F4: ki = kKeyF4; break;
    case XK_F5: ki = kKeyF5; break;
    case XK_F6: ki = kKeyF6; break;
    case XK_F7: ki = kKeyF7; break;
    case XK_F8: ki = kKeyF8; break;
    case XK_F9: ki = kKeyF9; break;
    case XK_F10: ki = kKeyF10; break;
    case XK_F11: ki = kKeyF11; break;
    case XK_F12: ki = kKeyF12; break;

    case XK_KP_0: ki = kKeyPad0; break;
    case XK_KP_1: ki = kKeyPad1; break;
    case XK_KP_2: ki = kKeyPad2; break;
    case XK_KP_3: ki = kKeyPad3; break;
    case XK_KP_4: ki = kKeyPad4; break;
    case XK_KP_5: ki = kKeyPad5; break;
    case XK_KP_6: ki = kKeyPad6; break;
    case XK_KP_7: ki = kKeyPad7; break;
    case XK_KP_8: ki = kKeyPad8; break;
    case XK_KP_9: ki = kKeyPad9; break;

    case XK_Left: ki = kKeyLeft; break;
    case XK_Right: ki = kKeyRight; break;
    case XK_Up: ki = kKeyUp; break;
    case XK_Down: ki = kKeyDown; break;

    case XK_BackSpace: ki = kKeyBackspace; break;
    case XK_Tab: ki = kKeyTab; break;
    case XK_KP_Enter: ki = kKeyPadEnter; break;
    case XK_Return: ki = kKeyReturn; break;
    case XK_Escape: ki = kKeyEscape; break;

    case XK_Shift_L: ki = kKeyLeftShift; break;
    case XK_Shift_R: ki = kKeyRightShift; break;
    case XK_Control_L: ki = kKeyLeftControl; break;
    case XK_Control_R: ki = kKeyRightControl; break;
    case XK_Alt_L: ki = kKeyLeftAlt; break;
    case XK_Alt_R: ki = kKeyRightAlt; break;
    case XK_Super_L: ki = kKeyLeftGui; break;
    case XK_Super_R: ki = kKeyRightGui; break;

    case XK_KP_Divide: ki = kKeyPadDivide; break;
    case XK_KP_Multiply: ki = kKeyPadMultiply; break;
    case XK_KP_Subtract: ki = kKeyPadSubtract; break;
    case XK_KP_Add: ki = kKeyPadAdd; break;

    case XK_dead_grave: ki = '`'; break;
    case XK_minus: ki = '-'; break;
    case XK_equal: ki = '='; break;
    case XK_bracketleft: ki = '['; break;
    case XK_bracketright: ki = ']'; break;
    case XK_backslash: ki = '\\'; break;
    case XK_semicolon: ki = ';'; break;
    case XK_dead_acute: ki = '\''; break;
    case XK_comma: ki = ','; break;
    case XK_period: ki = '.'; break;
    case XK_slash: ki = '/'; break;
    case XK_space: ki = '/'; break;
  }

  if(ki == 0)
    return false;

  *ev = Os::KeyEvent(ki, pushed, gt(), winx, winy, event.xkey.state & (1 << 4), event.xkey.state & LockMask);
  return true;
}
static bool SynthButton(int button, bool pushed, const XEvent &event, Window window, Os::KeyEvent *ev) {
  // mostly ignored
  Window root, child;
  int x, y, winx, winy;
  unsigned int mask;
  XQueryPointer(display, window, &root, &child, &x, &y, &winx, &winy, &mask);

  GlopKey ki;
  if(button == Button1)
    ki = kMouseLButton;
  else if(button == Button2)
    ki = kMouseMButton;
  else if(button == Button3)
    ki = kMouseRButton;
  /*
  else if(button == Button4)
    ki = kMouseWheelUp;   // these might be inverted so they're disabled for now
  else if(button == Button5)
    ki = kMouseWheelDown;*/
  else
    return false;

  *ev = Os::KeyEvent(ki, pushed, gt(), winx, winy, event.xkey.state & (1 << 4), event.xkey.state & LockMask);
  return true;
}

static bool SynthMotion(int dx, int dy, const XEvent &event, Window window, Os::KeyEvent *ev) {
  // mostly ignored
  Window root, child;
  int x, y, winx, winy;
  unsigned int mask;
  XQueryPointer(display, window, &root, &child, &x, &y, &winx, &winy, &mask);

  *ev = Os::KeyEvent(dx, dy, gt(), winx, winy, event.xkey.state & (1 << 4), event.xkey.state & LockMask);
  return true;
}

Bool EventTester(Display *display, XEvent *event, XPointer arg) {
  return true; // hurrr
}
void Os::Think() { } // we don't actually do anything here
void Os::WindowThink(OsWindowData* data) {
  XEvent event;
  while(XCheckIfEvent(display, &event, &EventTester, NULL)) {
    Os::KeyEvent ev(0, 0, 0, 0, 0); // fffff
    switch(event.type) {
      case KeyPress: {
        LOGF("keypress");
        char buf[2];
        KeySym sym;
        XComposeStatus status;

        XLookupString(&event.xkey, buf, sizeof(buf), &sym, &status);

        if(SynthKey(sym, true, event, data->window, &ev))
          events.push_back(ev);
        break;
      }

      case KeyRelease: {
        char buf[2];
        KeySym sym;
        XComposeStatus status;

        XLookupString(&event.xkey, buf, sizeof(buf), &sym, &status);

        if(SynthKey(sym, false, event, data->window, &ev))
          events.push_back(ev);
        break;
      }

      case ButtonPress:
        LOGF("buttonpress");
        if(SynthButton(event.xbutton.button, true, event, data->window, &ev))
          events.push_back(ev);
        break;

      case ButtonRelease:
        if(SynthButton(event.xbutton.button, false, event, data->window, &ev))
          events.push_back(ev);
        break;

      case MotionNotify:
        if(SynthMotion(event.xmotion.x, event.xmotion.y, event, data->window, &ev))
          events.push_back(ev);
        break;

      case FocusIn:
        XSetICFocus(data->inputcontext);
        break;

      case FocusOut:
        XUnsetICFocus(data->inputcontext);
        break;
    }
  }
}

OsWindowData* Os::CreateWindow(const string& title, int x, int y, int width, int height, bool full_screen, short stencil_bits, const Image* icon, bool is_resizable) {
  OsWindowData *nw = new OsWindowData();

  // this is bad
  if(x == -1) x = 100;
  if(y == -1) y = 100;

  // I think there's a way to specify more of this but I'll be damned if I can find it
  XVisualInfo vinfo_template;
  vinfo_template.screen = screen;
  int vinfo_ct;
  XVisualInfo *visualinfo = XGetVisualInfo(display, VisualScreenMask, &vinfo_template, &vinfo_ct);
  ASSERT(visualinfo);
  ASSERT(vinfo_ct);

  XVisualInfo vinfo;
  bool found = false;
  for(int i = 0; i < vinfo_ct; i++) {
    int use_gl, rgba, doublebuffer, red_size, green_size, blue_size, alpha_size;
    glXGetConfig(display, &visualinfo[i], GLX_USE_GL, &use_gl);
    glXGetConfig(display, &visualinfo[i], GLX_RGBA, &rgba);
    glXGetConfig(display, &visualinfo[i], GLX_DOUBLEBUFFER, &doublebuffer);
    glXGetConfig(display, &visualinfo[i], GLX_RED_SIZE, &red_size);
    glXGetConfig(display, &visualinfo[i], GLX_GREEN_SIZE, &green_size);
    glXGetConfig(display, &visualinfo[i], GLX_BLUE_SIZE, &blue_size);
    glXGetConfig(display, &visualinfo[i], GLX_ALPHA_SIZE, &alpha_size);
    //LOGF("%d %d %d %d %d %d %d", use_gl, rgba, doublebuffer, red_size, green_size, blue_size, alpha_size);

    if(use_gl && rgba && doublebuffer && red_size == 8 && green_size == 8 && blue_size == 8 && alpha_size == 8) {
      LOGF("Found something!");
      found = true;
      vinfo = visualinfo[i]; // I'm just going to hope the rest of the values are appropriate, because, really, who knows
      break;
    }
  }

  ASSERT(found);

  nw->context = glXCreateContext(display, &vinfo, NULL, True);
  ASSERT(nw->context);

  // Define the window attributes
  XSetWindowAttributes attribs;
  attribs.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask | FocusChangeMask;
  nw->window = XCreateWindow(display, RootWindow(display, screen), x, y, width, height, 0, vinfo.depth, InputOutput, vinfo.visual, CWEventMask, &attribs); // I don't know if I need anything further here

  SetTitle(nw, title);

  // I think in here is where we're meant to set window styles and stuff

  nw->inputcontext = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, nw->window, XNFocusWindow, nw->window, NULL);
  ASSERT(nw->inputcontext);

  XFree(visualinfo);

  XMapWindow(display, nw->window);

  SetCurrentContext(nw);

  return nw;
}

void Os::SetCurrentContext(OsWindowData* data) {
  glXMakeCurrent(display, data->window, data->context);
}

// Destroys a window that is completely or partially created.
void Os::DestroyWindow(OsWindowData* data) {
  delete data;
}

bool Os::IsWindowMinimized(const OsWindowData* data) {
  return false;
}

void Os::GetWindowFocusState(OsWindowData* data, bool* is_in_focus, bool* focus_changed) {
  *is_in_focus = true;
  *focus_changed = false;
}

void Os::GetWindowPosition(const OsWindowData* data, int* x, int* y) {
  XWindowAttributes attrs;
  XGetWindowAttributes(display, data->window, &attrs);
  *x = attrs.x;
  *y = attrs.y;
}

void Os::GetWindowSize(const OsWindowData* data, int* width, int* height) {
  XWindowAttributes attrs;
  XGetWindowAttributes(display, data->window, &attrs);
  *width  = attrs.width;
  *height = attrs.height;
}

void Os::SetTitle(OsWindowData* data, const string& title) {
  XStoreName(display, data->window, title.c_str());
}

void Os::SetIcon(OsWindowData *window, const Image *icon) {
  fprintf(stderr, "Os::SetIcon(%p, %p)\n", window, icon); // TBI
}

void Os::SetWindowSize(OsWindowData *window, int width, int height) {
  fprintf(stderr, "Os::SetWindowSize(%p, %d, %d)\n", window, width, height); // TBI
}

// Input functions
// ===============

// See Os.h

vector<Os::KeyEvent> Os::GetInputEvents(OsWindowData *window) {
  vector<Os::KeyEvent> ret; // weeeeeeeeeeee
  ret.swap(events);

  Window root, child;
  int x, y, winx, winy;
  unsigned int mask;
  XQueryPointer(display, window->window, &root, &child, &x, &y, &winx, &winy, &mask);

  if(ret.size())
    LOGF("%d events\n", ret.size());

  ret.push_back(Os::KeyEvent(gt(), winx, winy, mask & (1 << 4), mask & LockMask));

  return ret;
}

void Os::SetMousePosition(int x, int y) { // TBI
}

void Os::ShowMouseCursor(bool is_shown) { // TBI
}

void Os::RefreshJoysticks(OsWindowData *window) { // TBI
}

int Os::GetNumJoysticks(OsWindowData *window) { // TBI
  return 0;
}

// Threading functions
// ===================

#include <pthread.h>

void Os::StartThread(void(*thread_function)(void*), void* data) {
  pthread_t thread;
  if (pthread_create(&thread, NULL, (void*(*)(void*))thread_function, data) != 0) {
    printf("Error forking thread\n");
  }
}

struct OsMutex {
  pthread_mutex_t mutex;
};

OsMutex* Os::NewMutex() {
  OsMutex* mutex = new OsMutex;
  pthread_mutex_init(&mutex->mutex, NULL);
  return mutex;
}

void Os::DeleteMutex(OsMutex* mutex) {
  pthread_mutex_destroy(&mutex->mutex);
  delete mutex;
}

void Os::AcquireMutex(OsMutex* mutex) {
  pthread_mutex_lock(&mutex->mutex);
}

void Os::ReleaseMutex(OsMutex* mutex) {
  pthread_mutex_unlock(&mutex->mutex);
}

// Miscellaneous functions
// =======================

void Os::MessageBox(const string& title, const string& message) { // TBI
  fprintf(stderr,"MessageBox [%s]: [%s]\n", title.c_str(), message.c_str());
}

vector<pair<int, int> > Os::GetFullScreenModes() { // TBI
  return vector<pair<int, int> >(1,pair<int, int>(640,480));
}

void Os::Sleep(int t) {
  usleep(t*1000);
}

int Os::GetTime() {
  return gt();
}
long long Os::GetTimeMicro() {
  return gtm();
}

void Os::SwapBuffers(OsWindowData* data) {
  glXSwapBuffers(display, data->window);
}

int Os::GetRefreshRate() { // TBI
  //fprintf(stderr,"OS::GetRefreshRate()\n");
  return 60;
}

void Os::EnableVSync(bool is_enable) { // TBI
  fprintf(stderr,"OS::EnableVSync(%d)\n", is_enable);
}

vector<string> Os::ListFiles(const string &directory) { // TBI
  fprintf(stderr,"OS::ListFiles(%s)\n", directory.c_str());
  return vector<string>();
}

vector<string> Os::ListSubdirectories(const string &directory) { // TBI
  fprintf(stderr,"OS::ListSubdirectories(%s)\n", directory.c_str());
  return vector<string>();
}

#endif // LINUX

<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2017 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <kprint>
#include <info>
#include <service>
#include <smp>
#include <boot/multiboot.h>

extern  void default_stdout_handlers();
extern  void __platform_init();

extern "C" {
  void __init_serial1();
  void __init_sanity_checks();
  void kernel_sanity_checks();
  uintptr_t _multiboot_free_begin(uintptr_t boot_addr);
  uintptr_t _move_symbols(uintptr_t loc);
  void _init_bss();
  void _init_heap(uintptr_t);
  void _init_c_runtime();
  void _init_syscalls();
  void __libc_init_array();
  uintptr_t _end;
}

extern "C"
void kernel_start(uintptr_t magic, uintptr_t addr)
{

  // Initialize serial port 1
  __init_serial1();

  // generate checksums of read-only areas etc.
  __init_sanity_checks();

  // Determine where free memory starts
  uintptr_t free_mem_begin = reinterpret_cast<uintptr_t>(&_end);

  if (magic == MULTIBOOT_BOOTLOADER_MAGIC) {
    free_mem_begin = _multiboot_free_begin(addr);
  }

  // Preserve symbols from the ELF binary
  free_mem_begin += _move_symbols(free_mem_begin);

  // Initialize zero-initialized vars
  _init_bss();

  // Initialize heap
  _init_heap(free_mem_begin);

  //Initialize stack-unwinder, call global constructors etc.
  _init_c_runtime();

  // Initialize system calls
  _init_syscalls();

  //Initialize stdout handlers
  default_stdout_handlers();

  // Call global ctors
  __libc_init_array();

  __platform_init();

  // Start the service
  Service::start();

  // verify certain read-only sections in memory
  kernel_sanity_checks();

  __arch_poweroff();
}
<commit_msg>x86_nano: Update to new stdout mechanic<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2017 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <kprint>
#include <info>
#include <kernel/os.hpp>
#include <kernel/service.hpp>
#include <boot/multiboot.h>

extern  void __platform_init();

extern "C" {
  void __init_serial1();
  void __init_sanity_checks();
  void kernel_sanity_checks();
  uintptr_t _multiboot_free_begin(uintptr_t boot_addr);
  uintptr_t _move_symbols(uintptr_t loc);
  void _init_bss();
  void _init_heap(uintptr_t);
  void _init_c_runtime();
  void _init_syscalls();
  void __libc_init_array();
  uintptr_t _end;
}

extern "C"
void kernel_start(uintptr_t magic, uintptr_t addr)
{
  // Initialize serial port 1
  __init_serial1();

  // generate checksums of read-only areas etc.
  __init_sanity_checks();

  // Determine where free memory starts
  uintptr_t free_mem_begin = reinterpret_cast<uintptr_t>(&_end);

  if (magic == MULTIBOOT_BOOTLOADER_MAGIC) {
    free_mem_begin = _multiboot_free_begin(addr);
  }

  // Preserve symbols from the ELF binary
  free_mem_begin += _move_symbols(free_mem_begin);

  // Initialize zero-initialized vars
  _init_bss();

  // Initialize heap
  _init_heap(free_mem_begin);

  //Initialize stack-unwinder, call global constructors etc.
  _init_c_runtime();

  // Initialize system calls
  _init_syscalls();

  //Initialize stdout handlers
  OS::add_stdout(&OS::default_stdout);

  // Call global ctors
  __libc_init_array();

  __platform_init();

  // Start the service
  Service::start();

  // verify certain read-only sections in memory
  kernel_sanity_checks();

  __arch_poweroff();
}
<|endoftext|>


<commit_before><commit_msg>Revert "fix setting of paper tray from print dialog (fdo#43932)"<commit_after><|endoftext|>


<commit_before><commit_msg>assert on attempt to print after cancel<commit_after><|endoftext|>