<commit_before>/** \file    augment_canones_references.cc
 *  \brief   A tool for adding numerical canon law references to MARC-21 datasets.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2019, Library of the University of Tübingen

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

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <string>
#include <unordered_map>
#include <cstdlib>
#include "BibleUtil.h"
#include "Compiler.h"
#include "MARC.h"
#include "StringUtil.h"
#include "UBTools.h"
#include "util.h"

namespace {

void ParseRanges(const std::string &ppn, const std::string &ranges, unsigned * const range_start, unsigned * const range_end) {
    std::vector<std::string> parts;
    if (unlikely(StringUtil::SplitThenTrimWhite(ranges, ',', &parts, /* suppress_empty_components = */false) > 3))
        LOG_ERROR("bad codex parts \"" + ranges + "\"! (PPN: " + ppn + ")");

    unsigned canones;
    if (parts.size() == 1) {
        const auto dash_pos(parts[0].find('-'));
        if (dash_pos == std::string::npos) {
            if (unlikely(not StringUtil::ToUnsigned(parts[0], &canones)))
                LOG_ERROR("bad codex canones \"" + parts[0] + "\"! (PPN: " + ppn + ")");
            *range_start = canones * 10000;
            *range_end   = canones * 10000 + 9999;
        } else {
            if (unlikely(not StringUtil::ToUnsigned(parts[0].substr(0, dash_pos), range_start)
                         or not StringUtil::ToUnsigned(parts[0].substr(dash_pos + 1), range_end)))
                LOG_ERROR("bad canones range \"" + parts[0] + "\"! (PPN: " + ppn + ")");
            *range_start *= 10000;
            *range_end   *= 10000;
        }

        return;
    } else if (parts.size() == 2) {
        if (unlikely(not StringUtil::ToUnsigned(parts[0], &canones)))
            LOG_ERROR("bad codex canones \"" + parts[0] + "\"! (PPN: " + ppn + ")");

        const auto dash_pos(parts[1].find('-'));
        if (dash_pos == std::string::npos) {
            unsigned pars;
            if (unlikely(not StringUtil::ToUnsigned(parts[1], &pars)))
                LOG_ERROR("bad codex pars \"" + parts[1] + "\"! (PPN: " + ppn + ")");
            *range_start = canones * 10000 + pars * 100;
            *range_end   = canones * 10000 + 9999;
        } else {
            unsigned start_pars, end_pars;
            if (unlikely(not StringUtil::ToUnsigned(parts[1].substr(0, dash_pos), &start_pars)
                         or not StringUtil::ToUnsigned(parts[1].substr(dash_pos + 1), &end_pars)))
                LOG_ERROR("bad pars range \"" + parts[1] + "\"! (PPN: " + ppn + ")");
            *range_start = canones * 10000 + start_pars * 100;
            *range_end   = canones * 10000 + end_pars   * 100 + 99;
        }

        return;
    }

    LOG_ERROR("don't know how to parse codex parts \"" + ranges + "\"! (PPN: " + ppn + ")");
}

// To understand this code read https://github.com/ubtue/tuefind/wiki/Codices
std::string FieldToCanonLawCode(const std::string &ppn, const MARC::Record::Field &_110_field) {
    const std::string t_subfield(_110_field.getFirstSubfieldWithCode('t'));
    const std::string year(_110_field.getFirstSubfieldWithCode('f'));
    const std::string p_subfield(_110_field.getFirstSubfieldWithCode('p'));

    enum Codex { CIC1917, CIC1983, CCEO } codex;
    if (t_subfield == "Codex canonum ecclesiarum orientalium")
        codex = CCEO;
    else {
        if (unlikely(year.empty()))
            LOG_ERROR("missing year for Codex Iuris Canonici!");
        if (year == "1917")
            codex = CIC1917;
        else if (year == "1983")
            codex = CIC1983;
        else
            LOG_ERROR("bad year for Codex Iuris Canonici \"" + year + "\"!");
    }

    unsigned range_start, range_end;
    if (p_subfield.empty()) {
        range_start = 0;
        range_end = 99999999;
    } else
        ParseRanges(ppn, p_subfield, &range_start, &range_end);

    switch (codex) {
    case CIC1917:
        return StringUtil::ToString(100000000 + range_start) + "_" + StringUtil::ToString(100000000 + range_end);
    case CIC1983:
        return StringUtil::ToString(200000000 + range_start) + "_" + StringUtil::ToString(200000000 + range_end);
    case CCEO:
        return StringUtil::ToString(300000000 + range_start) + "_" + StringUtil::ToString(300000000 + range_end);
    }
}

void LoadAuthorityData(MARC::Reader * const reader,
                       std::unordered_map<std::string, std::string> * const authority_ppns_to_canon_law_codes_map)
{
    unsigned total_count(0);
    while (auto record = reader->read()) {
        ++total_count;

        const auto _110_field(record.findTag("110"));
        if (_110_field == record.end() or _110_field->getFirstSubfieldWithCode('a') != "Katholische Kirche")
            continue;

        const std::string t_subfield(_110_field->getFirstSubfieldWithCode('t'));
        if (t_subfield != "Codex Iuris Canonici" and t_subfield != "Codex canonum ecclesiarum orientalium")
            continue;

        (*authority_ppns_to_canon_law_codes_map)[record.getControlNumber()] = FieldToCanonLawCode(record.getControlNumber(), *_110_field);
    }

    LOG_INFO("found " + std::to_string(authority_ppns_to_canon_law_codes_map->size()) + " canon law records among "
             + std::to_string(total_count) + " authority records.");
}

void ProcessRecords(MARC::Reader * const reader, MARC::Writer * const writer,
                    const std::unordered_map<std::string, std::string> &authority_ppns_to_canon_law_codes_map)
{
    unsigned total_count(0), augmented_count(0);
    while (auto record = reader->read()) {
        ++total_count;

        bool augmented_record(false);
        for (const auto &_689_field : record.getTagRange("689")) {
            if (_689_field.getFirstSubfieldWithCode('2') != "gnd")
                continue;

            std::vector<std::string> authority_ppns;
            for (const auto &subfield : _689_field.getSubfields()) {
                if (subfield.code_ == '0' and StringUtil::StartsWith(subfield.value_, "(DE-576)"))
                    authority_ppns.emplace_back(subfield.value_.substr(__builtin_strlen("(DE-576)")));
            }

            for (const auto &authority_ppn : authority_ppns) {
                const auto ppn_and_canon_law_code(authority_ppns_to_canon_law_codes_map.find(authority_ppn));
                if (ppn_and_canon_law_code != authority_ppns_to_canon_law_codes_map.cend()) {
                    record.insertField("CAL", { { 'a', ppn_and_canon_law_code->second } });
                    augmented_record = true;
                }
            }
        }
        if (augmented_record)
            ++augmented_count;

        writer->write(record);
    }

    LOG_INFO("augmented " + std::to_string(augmented_count) + " of " + std::to_string(total_count) + " records.");
}

} // unnamed namespace

int Main(int argc, char **argv) {
    if (argc != 4)
        ::Usage("ix_theo_titles authority_records augmented_ix_theo_titles");

    const std::string title_input_filename(argv[1]);
    const std::string authority_filename(argv[2]);
    const std::string title_output_filename(argv[3]);
    if (unlikely(title_input_filename == title_output_filename))
        LOG_ERROR("Title input file name equals title output file name!");
    if (unlikely(title_input_filename == authority_filename))
        LOG_ERROR("Title input file name equals authority file name!");
    if (unlikely(title_output_filename == authority_filename))
        LOG_ERROR("Title output file name equals authority file name!");

    auto authority_reader(MARC::Reader::Factory(authority_filename));
    std::unordered_map<std::string, std::string> authority_ppns_to_canon_law_codes_map;
    LoadAuthorityData(authority_reader.get(), &authority_ppns_to_canon_law_codes_map);

    auto title_reader(MARC::Reader::Factory(title_input_filename));
    auto title_writer(MARC::Writer::Factory(title_output_filename));
    ProcessRecords(title_reader.get(), title_writer.get(), authority_ppns_to_canon_law_codes_map);

    return EXIT_SUCCESS;
}
<commit_msg>Update augment_canones_references.cc<commit_after>/** \file    augment_canones_references.cc
 *  \brief   A tool for adding numerical canon law references to MARC-21 datasets.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2019, Library of the University of Tübingen

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

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <string>
#include <unordered_map>
#include <cstdlib>
#include "BibleUtil.h"
#include "Compiler.h"
#include "MARC.h"
#include "StringUtil.h"
#include "UBTools.h"
#include "util.h"

namespace {

void ParseRanges(const std::string &ppn, const std::string &ranges, unsigned * const range_start, unsigned * const range_end) {
    std::vector<std::string> parts;
    if (unlikely(StringUtil::SplitThenTrimWhite(ranges, ',', &parts, /* suppress_empty_components = */false) > 3))
        LOG_ERROR("bad codex parts \"" + ranges + "\"! (PPN: " + ppn + ")");

    unsigned canones;
    if (parts.size() == 1) {
        const auto dash_pos(parts[0].find('-'));
        if (dash_pos == std::string::npos) {
            if (unlikely(not StringUtil::ToUnsigned(parts[0], &canones)))
                LOG_ERROR("bad codex canones \"" + parts[0] + "\"! (PPN: " + ppn + ")");
            *range_start = canones * 10000;
            *range_end   = canones * 10000 + 9999;
        } else {
            if (unlikely(not StringUtil::ToUnsigned(parts[0].substr(0, dash_pos), range_start)
                         or not StringUtil::ToUnsigned(parts[0].substr(dash_pos + 1), range_end)))
                LOG_ERROR("bad canones range \"" + parts[0] + "\"! (PPN: " + ppn + ")");
            *range_start *= 10000;
            *range_end   *= 10000;
        }

        return;
    } else if (parts.size() == 2) {
        if (unlikely(not StringUtil::ToUnsigned(parts[0], &canones)))
            LOG_ERROR("bad codex canones \"" + parts[0] + "\"! (PPN: " + ppn + ")");

        const auto dash_pos(parts[1].find('-'));
        if (dash_pos == std::string::npos) {
            unsigned pars;
            if (unlikely(not StringUtil::ToUnsigned(parts[1], &pars)))
                LOG_ERROR("bad codex pars \"" + parts[1] + "\"! (PPN: " + ppn + ")");
            *range_start = canones * 10000 + pars * 100;
            *range_end   = canones * 10000 + 9999;
        } else {
            unsigned start_pars, end_pars;
            if (unlikely(not StringUtil::ToUnsigned(parts[1].substr(0, dash_pos), &start_pars)
                         or not StringUtil::ToUnsigned(parts[1].substr(dash_pos + 1), &end_pars)))
                LOG_ERROR("bad pars range \"" + parts[1] + "\"! (PPN: " + ppn + ")");
            *range_start = canones * 10000 + start_pars * 100;
            *range_end   = canones * 10000 + end_pars   * 100 + 99;
        }

        return;
    }

    LOG_ERROR("don't know how to parse codex parts \"" + ranges + "\"! (PPN: " + ppn + ")");
}

// To understand this code read https://github.com/ubtue/tuefind/wiki/Codices
std::string FieldToCanonLawCode(const std::string &ppn, const MARC::Record::Field &_110_field) {
    const std::string t_subfield(_110_field.getFirstSubfieldWithCode('t'));
    const std::string year(_110_field.getFirstSubfieldWithCode('f'));
    const std::string p_subfield(_110_field.getFirstSubfieldWithCode('p'));

    enum Codex { CIC1917, CIC1983, CCEO } codex;
    if (t_subfield == "Codex canonum ecclesiarum orientalium")
        codex = CCEO;
    else {
        if (unlikely(year.empty()))
            LOG_ERROR("missing year for Codex Iuris Canonici!");
        if (year == "1917")
            codex = CIC1917;
        else if (year == "1983")
            codex = CIC1983;
        else
            LOG_ERROR("bad year for Codex Iuris Canonici \"" + year + "\"!");
    }

    unsigned range_start, range_end;
    if (p_subfield.empty()) {
        range_start = 0;
        range_end = 99999999;
    } else
        ParseRanges(ppn, p_subfield, &range_start, &range_end);

    switch (codex) {
    case CIC1917:
        return StringUtil::ToString(100000000 + range_start) + "_" + StringUtil::ToString(100000000 + range_end);
    case CIC1983:
        return StringUtil::ToString(200000000 + range_start) + "_" + StringUtil::ToString(200000000 + range_end);
    case CCEO:
        return StringUtil::ToString(300000000 + range_start) + "_" + StringUtil::ToString(300000000 + range_end);
    }
}

void LoadAuthorityData(MARC::Reader * const reader,
                       std::unordered_map<std::string, std::string> * const authority_ppns_to_canon_law_codes_map)
{
    unsigned total_count(0);
    while (auto record = reader->read()) {
        ++total_count;

        const auto _110_field(record.findTag("110"));
        if (_110_field == record.end() or _110_field->getFirstSubfieldWithCode('a') != "Katholische Kirche")
            continue;

        const std::string t_subfield(_110_field->getFirstSubfieldWithCode('t'));
        if (t_subfield != "Codex Iuris Canonici" and t_subfield != "Codex canonum ecclesiarum orientalium")
            continue;

        (*authority_ppns_to_canon_law_codes_map)[record.getControlNumber()] = FieldToCanonLawCode(record.getControlNumber(), *_110_field);
    }

    LOG_INFO("found " + std::to_string(authority_ppns_to_canon_law_codes_map->size()) + " canon law records among "
             + std::to_string(total_count) + " authority records.");
}

void ProcessRecords(MARC::Reader * const reader, MARC::Writer * const writer,
                    const std::unordered_map<std::string, std::string> &authority_ppns_to_canon_law_codes_map)
{
    unsigned total_count(0), augmented_count(0);
    while (auto record = reader->read()) {
        ++total_count;

        bool augmented_record(false);
        for (const auto &_689_field : record.getTagRange("689")) {
            if (_689_field.getFirstSubfieldWithCode('2') != "gnd")
                continue;

            std::vector<std::string> authority_ppns;
            for (const auto &subfield : _689_field.getSubfields()) {
                if (subfield.code_ == '0' and StringUtil::StartsWith(subfield.value_, "(DE-576)"))
                    authority_ppns.emplace_back(subfield.value_.substr(__builtin_strlen("(DE-576)")));
            }

            for (const auto &authority_ppn : authority_ppns) {
                const auto ppn_and_canon_law_code(authority_ppns_to_canon_law_codes_map.find(authority_ppn));
                if (ppn_and_canon_law_code != authority_ppns_to_canon_law_codes_map.cend()) {
                    record.insertField("CAL", { { 'a', ppn_and_canon_law_code->second } });
                    augmented_record = true;
                }
            }
        }
        if (augmented_record)
            ++augmented_count;

        writer->write(record);
    }

    LOG_INFO("augmented " + std::to_string(augmented_count) + " of " + std::to_string(total_count) + " records.");
}

} // unnamed namespace

int Main(int argc, char **argv) {
    if (argc != 4)
        ::Usage("ixtheo_titles authority_records augmented_ixtheo_titles");

    const std::string title_input_filename(argv[1]);
    const std::string authority_filename(argv[2]);
    const std::string title_output_filename(argv[3]);
    if (unlikely(title_input_filename == title_output_filename))
        LOG_ERROR("Title input file name equals title output file name!");
    if (unlikely(title_input_filename == authority_filename))
        LOG_ERROR("Title input file name equals authority file name!");
    if (unlikely(title_output_filename == authority_filename))
        LOG_ERROR("Title output file name equals authority file name!");

    auto authority_reader(MARC::Reader::Factory(authority_filename));
    std::unordered_map<std::string, std::string> authority_ppns_to_canon_law_codes_map;
    LoadAuthorityData(authority_reader.get(), &authority_ppns_to_canon_law_codes_map);

    auto title_reader(MARC::Reader::Factory(title_input_filename));
    auto title_writer(MARC::Writer::Factory(title_output_filename));
    ProcessRecords(title_reader.get(), title_writer.get(), authority_ppns_to_canon_law_codes_map);

    return EXIT_SUCCESS;
}
<|endoftext|>


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

#include <lineaction.hxx>
#include <outdevstate.hxx>

#ifndef _RTL_LOGFILE_HXX_
#include <rtl/logfile.hxx>
#endif
#ifndef _COM_SUN_STAR_RENDERING_XCANVAS_HPP_
#include <com/sun/star/rendering/XCanvas.hpp>
#endif

#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef _VCL_CANVASTOOLS_HXX
#include <vcl/canvastools.hxx>
#endif

#ifndef _BGFX_RANGE_B2DRANGE_HXX
#include <basegfx/range/b2drange.hxx>
#endif
#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX
#include <basegfx/tools/canvastools.hxx>
#endif
#ifndef _CANVAS_CANVASTOOLS_HXX
#include <canvas/canvastools.hxx>
#endif

#include <boost/utility.hpp>

#include <cppcanvas/canvas.hxx>

#include <mtftools.hxx>

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

namespace cppcanvas
{
    namespace internal
    {
        namespace
        {
            class LineAction : public Action, private ::boost::noncopyable
            {
            public:
                LineAction( const ::Point&,
                            const ::Point&,
                            const CanvasSharedPtr&,
                            const OutDevState& );

                virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation ) const;
                virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
                                     const Subset&                  rSubset ) const;

                virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
                virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix&   rTransformation,
                                                       const Subset&                    rSubset ) const;

                virtual sal_Int32 getActionCount() const;

            private:
                Point                   maStartPoint;
                Point                   maEndPoint;
                CanvasSharedPtr         mpCanvas;
                rendering::RenderState  maState;
            };

            LineAction::LineAction( const ::Point&          rStartPoint,
                                    const ::Point&          rEndPoint,
                                    const CanvasSharedPtr&  rCanvas,
                                    const OutDevState&      rState ) :
                maStartPoint( rStartPoint ),
                maEndPoint( rEndPoint ),
                mpCanvas( rCanvas ),
                maState()
            {
                tools::initRenderState(maState,rState);
                maState.DeviceColor = rState.lineColor;
            }

            bool LineAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const
            {
                RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::LineAction::render()" );
                RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::LineAction: 0x%X", this );

                rendering::RenderState aLocalState( maState );
                ::canvas::tools::prependToRenderState(aLocalState, rTransformation);

                mpCanvas->getUNOCanvas()->drawLine( ::vcl::unotools::point2DFromPoint(maStartPoint),
                                                    ::vcl::unotools::point2DFromPoint(maEndPoint),
                                                    mpCanvas->getViewState(),
                                                    aLocalState );

                return true;
            }

            bool LineAction::render( const ::basegfx::B2DHomMatrix& rTransformation,
                                     const Subset&                  rSubset ) const
            {
                // line only contains a single action, fail if subset
                // requests different range
                if( rSubset.mnSubsetBegin != 0 ||
                    rSubset.mnSubsetEnd != 1 )
                    return false;

                return render( rTransformation );
            }

            ::basegfx::B2DRange LineAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
            {
                rendering::RenderState aLocalState( maState );
                ::canvas::tools::prependToRenderState(aLocalState, rTransformation);

                return tools::calcDevicePixelBounds( ::basegfx::B2DRange( maStartPoint.X(),
                                                                          maStartPoint.Y(),
                                                                          maEndPoint.X(),
                                                                          maEndPoint.Y() ),
                                                     mpCanvas->getViewState(),
                                                     aLocalState );
            }

            ::basegfx::B2DRange LineAction::getBounds( const ::basegfx::B2DHomMatrix&   rTransformation,
                                                       const Subset&                    rSubset ) const
            {
                // line only contains a single action, empty bounds
                // if subset requests different range
                if( rSubset.mnSubsetBegin != 0 ||
                    rSubset.mnSubsetEnd != 1 )
                    return ::basegfx::B2DRange();

                return getBounds( rTransformation );
            }

            sal_Int32 LineAction::getActionCount() const
            {
                return 1;
            }
        }

        ActionSharedPtr LineActionFactory::createLineAction( const ::Point&         rStartPoint,
                                                             const ::Point&         rEndPoint,
                                                             const CanvasSharedPtr& rCanvas,
                                                             const OutDevState&     rState  )
        {
            return ActionSharedPtr( new LineAction( rStartPoint,
                                                    rEndPoint,
                                                    rCanvas,
                                                    rState) );
        }

    }
}
<commit_msg>INTEGRATION: CWS canvas02 (1.6.4); FILE MERGED 2005/10/09 09:11:49 thb 1.6.4.2: RESYNC: (1.6-1.7); FILE MERGED 2005/08/24 23:02:57 thb 1.6.4.1: #i52876# Added CachedPrimitiveBase base class for common XCachedPrimitive handling; removed external header guards from cxx files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: lineaction.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2005-11-02 13:40:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <lineaction.hxx>
#include <outdevstate.hxx>

#include <rtl/logfile.hxx>
#include <com/sun/star/rendering/XCanvas.hpp>

#include <tools/gen.hxx>
#include <vcl/canvastools.hxx>

#include <basegfx/range/b2drange.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <canvas/canvastools.hxx>

#include <boost/utility.hpp>

#include <cppcanvas/canvas.hxx>

#include <mtftools.hxx>

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

namespace cppcanvas
{
    namespace internal
    {
        namespace
        {
            class LineAction : public Action, private ::boost::noncopyable
            {
            public:
                LineAction( const ::Point&,
                            const ::Point&,
                            const CanvasSharedPtr&,
                            const OutDevState& );

                virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation ) const;
                virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
                                     const Subset&                  rSubset ) const;

                virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
                virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix&   rTransformation,
                                                       const Subset&                    rSubset ) const;

                virtual sal_Int32 getActionCount() const;

            private:
                Point                   maStartPoint;
                Point                   maEndPoint;
                CanvasSharedPtr         mpCanvas;
                rendering::RenderState  maState;
            };

            LineAction::LineAction( const ::Point&          rStartPoint,
                                    const ::Point&          rEndPoint,
                                    const CanvasSharedPtr&  rCanvas,
                                    const OutDevState&      rState ) :
                maStartPoint( rStartPoint ),
                maEndPoint( rEndPoint ),
                mpCanvas( rCanvas ),
                maState()
            {
                tools::initRenderState(maState,rState);
                maState.DeviceColor = rState.lineColor;
            }

            bool LineAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const
            {
                RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::LineAction::render()" );
                RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::LineAction: 0x%X", this );

                rendering::RenderState aLocalState( maState );
                ::canvas::tools::prependToRenderState(aLocalState, rTransformation);

                mpCanvas->getUNOCanvas()->drawLine( ::vcl::unotools::point2DFromPoint(maStartPoint),
                                                    ::vcl::unotools::point2DFromPoint(maEndPoint),
                                                    mpCanvas->getViewState(),
                                                    aLocalState );

                return true;
            }

            bool LineAction::render( const ::basegfx::B2DHomMatrix& rTransformation,
                                     const Subset&                  rSubset ) const
            {
                // line only contains a single action, fail if subset
                // requests different range
                if( rSubset.mnSubsetBegin != 0 ||
                    rSubset.mnSubsetEnd != 1 )
                    return false;

                return render( rTransformation );
            }

            ::basegfx::B2DRange LineAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
            {
                rendering::RenderState aLocalState( maState );
                ::canvas::tools::prependToRenderState(aLocalState, rTransformation);

                return tools::calcDevicePixelBounds( ::basegfx::B2DRange( maStartPoint.X(),
                                                                          maStartPoint.Y(),
                                                                          maEndPoint.X(),
                                                                          maEndPoint.Y() ),
                                                     mpCanvas->getViewState(),
                                                     aLocalState );
            }

            ::basegfx::B2DRange LineAction::getBounds( const ::basegfx::B2DHomMatrix&   rTransformation,
                                                       const Subset&                    rSubset ) const
            {
                // line only contains a single action, empty bounds
                // if subset requests different range
                if( rSubset.mnSubsetBegin != 0 ||
                    rSubset.mnSubsetEnd != 1 )
                    return ::basegfx::B2DRange();

                return getBounds( rTransformation );
            }

            sal_Int32 LineAction::getActionCount() const
            {
                return 1;
            }
        }

        ActionSharedPtr LineActionFactory::createLineAction( const ::Point&         rStartPoint,
                                                             const ::Point&         rEndPoint,
                                                             const CanvasSharedPtr& rCanvas,
                                                             const OutDevState&     rState  )
        {
            return ActionSharedPtr( new LineAction( rStartPoint,
                                                    rEndPoint,
                                                    rCanvas,
                                                    rState) );
        }

    }
}
<|endoftext|>


<commit_before>#include "n_text_list_selector.h"

#include <window/n_list_dialog.h>

#include <n_project.h>

NTextListSelector::NTextListSelector(QWidget *parent) : QPushButton(parent) {
    connect(this, SIGNAL(clicked()), this, SLOT(execListDialog()));

    this->setFlat(true);
    this->setStyleSheet("QPushButton { \
                        background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(200, 200, 200, 255)); \
                        border: 1px solid #aaaaaa; \
                        text-align: left;\
                      }");
}

NTextListSelector::NTextListSelector(TYPE type, QWidget *parent) : NTextListSelector(parent) {
    mType = type;
}

void NTextListSelector::setType(TYPE type) {
    mType = type;
}

NTextListSelector::TYPE NTextListSelector::getType() {
    return mType;
}

void NTextListSelector::setText(const QString &text) {
    QString oldText = this->text();
    QPushButton::setText(text);
    this->setToolTip(text);

    if (oldText != text) {
        emit this->textChanged(text);
    }
}

void NTextListSelector::execListDialog() {
    NListDialog dialog;

    QStringList list;
    switch(mType) {
    case LAYOUT:
        list = NProject::instance()->layouts();
        break;
    case PAGE:
        list = NProject::instance()->pages();
        break;
    case SCENE:
        list = NProject::instance()->scenes();
        break;
    case LINK:
        list = NProject::instance()->links();
        break;
    case IMAGE:
        list = NProject::instance()->images();
        break;
    }

    dialog.setTextList(list);
    dialog.setCurrentText(this->text());

    int exec = dialog.exec();
    if (exec == NListDialog::Accepted) {
        QString text = dialog.selectedText();
        this->setText(text);
    }

}
<commit_msg>styleをちょっと変更.<commit_after>#include "n_text_list_selector.h"

#include <window/n_list_dialog.h>

#include <n_project.h>

NTextListSelector::NTextListSelector(QWidget *parent) : QPushButton(parent) {
    connect(this, SIGNAL(clicked()), this, SLOT(execListDialog()));

    this->setFlat(true);
    this->setStyleSheet("QPushButton { \
                        text-align: left;\
                      }");
}

NTextListSelector::NTextListSelector(TYPE type, QWidget *parent) : NTextListSelector(parent) {
    mType = type;
}

void NTextListSelector::setType(TYPE type) {
    mType = type;
}

NTextListSelector::TYPE NTextListSelector::getType() {
    return mType;
}

void NTextListSelector::setText(const QString &text) {
    QString oldText = this->text();
    QPushButton::setText(text);
    this->setToolTip(text);

    if (oldText != text) {
        emit this->textChanged(text);
    }
}

void NTextListSelector::execListDialog() {
    NListDialog dialog;

    QStringList list;
    switch(mType) {
    case LAYOUT:
        list = NProject::instance()->layouts();
        break;
    case PAGE:
        list = NProject::instance()->pages();
        break;
    case SCENE:
        list = NProject::instance()->scenes();
        break;
    case LINK:
        list = NProject::instance()->links();
        break;
    case IMAGE:
        list = NProject::instance()->images();
        break;
    }

    dialog.setTextList(list);
    dialog.setCurrentText(this->text());

    int exec = dialog.exec();
    if (exec == NListDialog::Accepted) {
        QString text = dialog.selectedText();
        this->setText(text);
    }

}
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#ifndef DBAUI_QUERYDLG_HXX
#include "querydlg.hxx"
#endif
#ifndef _DBU_QRY_HRC_
#include "dbu_qry.hrc"
#endif
#ifndef DBAUI_QUERYDLG_HRC
#include "querydlg.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef DBAUI_QTABLECONNECTIONDATA_HXX
#include "QTableConnectionData.hxx"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef DBAUI_QUERYCONTROLLER_HXX
#include "querycontroller.hxx"
#endif
#ifndef DBAUI_QUERYTABLEVIEW_HXX
#include "QueryTableView.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNVIEW_HXX
#include "QueryDesignView.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
#endif
#ifndef DBAUI_RELATIONCONTROL_HXX
#include "RelationControl.hxx"
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif

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

DBG_NAME(DlgQryJoin)
DlgQryJoin::DlgQryJoin( Window * pParent,
                       OQueryTableConnectionData* _pData,
                       OJoinTableView::OTableWindowMap* _pTableMap,
                       const Reference< XConnection >& _xConnection,
                       BOOL _bAllowTableSelect)
    :ModalDialog( pParent, ModuleRes(DLG_QRY_JOIN) )
    ,aFL_Join( this, ResId( FL_JOIN ) )
    ,aFT_Title( this, ResId(FT_LISTBOXTITLE) )
    ,aLB_JoinType( this, ResId(LB_JOINTYPE) )
    ,aML_HelpText( this, ResId(ML_HELPTEXT) )
    ,aPB_OK( this, ResId( PB_OK ) )
    ,aPB_CANCEL( this, ResId( PB_CANCEL ) )
    ,aPB_HELP( this, ResId( PB_HELP ) )
    ,m_pTableControl( NULL )
    ,m_pTableMap(_pTableMap)
    ,eJoinType(_pData->GetJoinType())
    ,m_pConnData(NULL)
    ,m_pOrigConnData(_pData)
    ,m_xConnection(_xConnection)
{
    DBG_CTOR(DlgQryJoin,NULL);

    aML_HelpText.SetControlBackground( GetSettings().GetStyleSettings().GetFaceColor() );
    //////////////////////////////////////////////////////////////////////
    // Connection kopieren
    m_pConnData = static_cast<OQueryTableConnectionData*>(_pData->NewInstance());
    m_pConnData->CopyFrom(*_pData);

    m_pTableControl = new OTableListBoxControl(this,ModuleRes(WND_CONTROL),m_pTableMap,this);

    if( _bAllowTableSelect )
    {
        m_pTableControl->Init( m_pConnData );
        m_pTableControl->fillListBoxes();
    }
    else
    {
        m_pTableControl->fillAndDisable(m_pConnData);
        m_pTableControl->Init( m_pConnData );
    }

    m_pTableControl->lateInit();

    sal_Bool bFull = sal_False;
    sal_Bool bOuter = sal_False;
    Reference<XDatabaseMetaData> xMeta;
    try
    {
        xMeta = m_xConnection->getMetaData();
        if ( xMeta.is() )
            bFull = xMeta->supportsFullOuterJoins();
    }
    catch(SQLException&)
    {
    }
    try
    {
        if ( xMeta.is() )
            bOuter= xMeta->supportsOuterJoins();
    }
    catch(SQLException&)
    {
    }

    setJoinType(eJoinType);

    aPB_OK.SetClickHdl( LINK(this, DlgQryJoin, OKClickHdl) );

    aLB_JoinType.SetSelectHdl(LINK(this,DlgQryJoin,LBChangeHdl));

    if ( static_cast<OQueryTableView*>(pParent)->getDesignView()->getController()->isReadOnly() )
    {
        aLB_JoinType.Disable();
        m_pTableControl->Disable();
    }
    else if ( !bFull && !bOuter )
        aLB_JoinType.Disable();
    else
    {
        if ( !bFull )
            aLB_JoinType.RemoveEntry(3);

        if ( !bOuter )
        {
            aLB_JoinType.RemoveEntry(0);
            aLB_JoinType.RemoveEntry(0);
            aLB_JoinType.RemoveEntry(0);
        }

        m_pTableControl->NotifyCellChange();
    }

    FreeResource();
}

//------------------------------------------------------------------------
DlgQryJoin::~DlgQryJoin()
{
    DBG_DTOR(DlgQryJoin,NULL);
    delete m_pTableControl;
    delete m_pConnData;
}
// -----------------------------------------------------------------------------
IMPL_LINK( DlgQryJoin, LBChangeHdl, ListBox*, /*pListBox*/ )
{
    DBG_CHKTHIS(DlgQryJoin,NULL);
    aML_HelpText.SetText(String());

    String sFirstWinName,sSecondWinName;
    USHORT nResId = 0;
    USHORT nPos = aLB_JoinType.GetSelectEntryPos();
    sal_Bool bAddHint = sal_True;
    switch ( nPos )
    {
        default:
        case 0:
            nResId = STR_QUERY_INNER_JOIN;
            bAddHint = sal_False;
            break;
        case 1:
            nResId = STR_QUERY_LEFTRIGHT_JOIN;
            sFirstWinName   = m_pConnData->GetSourceWinName();
            sSecondWinName  = m_pConnData->GetDestWinName();
            break;
        case 2:
        case 3:
            nResId = (nPos == 2) ? STR_QUERY_LEFTRIGHT_JOIN : STR_QUERY_FULL_JOIN;

            sFirstWinName   = m_pConnData->GetDestWinName();
            sSecondWinName  = m_pConnData->GetSourceWinName();
            break;
    }

    String sHelpText = String( ModuleRes( nResId ) );
    if( sFirstWinName.Len() )
    {
        sHelpText.SearchAndReplace( String( RTL_CONSTASCII_STRINGPARAM( "%1" ) ), sFirstWinName );
        sHelpText.SearchAndReplace( String( RTL_CONSTASCII_STRINGPARAM( "%2" ) ), sSecondWinName );
    }
    if ( bAddHint )
    {
        sHelpText += String( RTL_CONSTASCII_STRINGPARAM( "\n" ) );
        sHelpText += String( ModuleRes( STR_JOIN_TYPE_HINT ) );
    }

    aML_HelpText.SetText( sHelpText );
    return 1;
}
// -----------------------------------------------------------------------------

IMPL_LINK( DlgQryJoin, OKClickHdl, Button*, /*pButton*/ )
{
    DBG_CHKTHIS(DlgQryJoin,NULL);
    USHORT nPos = aLB_JoinType.GetSelectEntryPos();
    switch ( nPos )
    {
        case 0:
            eJoinType = INNER_JOIN;
            break;
        case 1:
            eJoinType = LEFT_JOIN;
            break;
        case 2:
            eJoinType = RIGHT_JOIN;
            break;
        case 3:
            eJoinType = FULL_JOIN;
            break;
    }

    m_pConnData->Update();
    m_pOrigConnData->CopyFrom( *m_pConnData );

    EndDialog(RET_OK);
    return 1;
}
// -----------------------------------------------------------------------------
OTableConnectionData* DlgQryJoin::getConnectionData() const
{
    return m_pConnData;
}
// -----------------------------------------------------------------------------
void DlgQryJoin::setValid(sal_Bool _bValid)
{
    LBChangeHdl(&aLB_JoinType);

    aPB_OK.Enable(_bValid);
}
// -----------------------------------------------------------------------------
void DlgQryJoin::notifyConnectionChange( )
{
    setJoinType( m_pConnData->GetJoinType() );
}
// -----------------------------------------------------------------------------
void DlgQryJoin::setJoinType(EJoinType _eNewJoinType)
{
    eJoinType = _eNewJoinType;
    USHORT nPos = 0;
    switch(eJoinType)
    {
        case INNER_JOIN:
            break;
        case LEFT_JOIN:
            nPos = 1;
            break;
        case RIGHT_JOIN:
            nPos = 2;
            break;
        case FULL_JOIN:
            nPos = 3;
            break;
        default:
            break;
    }
    aLB_JoinType.SelectEntryPos(nPos);
    LBChangeHdl(&aLB_JoinType);
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS residcleanup (1.13.80); FILE MERGED 2007/02/26 22:58:52 pl 1.13.80.1: #i74635# no more ResMgr default<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: querydlg.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-26 08:03:08 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#ifndef DBAUI_QUERYDLG_HXX
#include "querydlg.hxx"
#endif
#ifndef _DBU_QRY_HRC_
#include "dbu_qry.hrc"
#endif
#ifndef DBAUI_QUERYDLG_HRC
#include "querydlg.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef DBAUI_QTABLECONNECTIONDATA_HXX
#include "QTableConnectionData.hxx"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef DBAUI_QUERYCONTROLLER_HXX
#include "querycontroller.hxx"
#endif
#ifndef DBAUI_QUERYTABLEVIEW_HXX
#include "QueryTableView.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNVIEW_HXX
#include "QueryDesignView.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
#endif
#ifndef DBAUI_RELATIONCONTROL_HXX
#include "RelationControl.hxx"
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif

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

DBG_NAME(DlgQryJoin)
DlgQryJoin::DlgQryJoin( Window * pParent,
                       OQueryTableConnectionData* _pData,
                       OJoinTableView::OTableWindowMap* _pTableMap,
                       const Reference< XConnection >& _xConnection,
                       BOOL _bAllowTableSelect)
    :ModalDialog( pParent, ModuleRes(DLG_QRY_JOIN) )
    ,aFL_Join( this, ModuleRes( FL_JOIN ) )
    ,aFT_Title( this, ModuleRes(FT_LISTBOXTITLE) )
    ,aLB_JoinType( this, ModuleRes(LB_JOINTYPE) )
    ,aML_HelpText( this, ModuleRes(ML_HELPTEXT) )
    ,aPB_OK( this, ModuleRes( PB_OK ) )
    ,aPB_CANCEL( this, ModuleRes( PB_CANCEL ) )
    ,aPB_HELP( this, ModuleRes( PB_HELP ) )
    ,m_pTableControl( NULL )
    ,m_pTableMap(_pTableMap)
    ,eJoinType(_pData->GetJoinType())
    ,m_pConnData(NULL)
    ,m_pOrigConnData(_pData)
    ,m_xConnection(_xConnection)
{
    DBG_CTOR(DlgQryJoin,NULL);

    aML_HelpText.SetControlBackground( GetSettings().GetStyleSettings().GetFaceColor() );
    //////////////////////////////////////////////////////////////////////
    // Connection kopieren
    m_pConnData = static_cast<OQueryTableConnectionData*>(_pData->NewInstance());
    m_pConnData->CopyFrom(*_pData);

    m_pTableControl = new OTableListBoxControl(this,ModuleRes(WND_CONTROL),m_pTableMap,this);

    if( _bAllowTableSelect )
    {
        m_pTableControl->Init( m_pConnData );
        m_pTableControl->fillListBoxes();
    }
    else
    {
        m_pTableControl->fillAndDisable(m_pConnData);
        m_pTableControl->Init( m_pConnData );
    }

    m_pTableControl->lateInit();

    sal_Bool bFull = sal_False;
    sal_Bool bOuter = sal_False;
    Reference<XDatabaseMetaData> xMeta;
    try
    {
        xMeta = m_xConnection->getMetaData();
        if ( xMeta.is() )
            bFull = xMeta->supportsFullOuterJoins();
    }
    catch(SQLException&)
    {
    }
    try
    {
        if ( xMeta.is() )
            bOuter= xMeta->supportsOuterJoins();
    }
    catch(SQLException&)
    {
    }

    setJoinType(eJoinType);

    aPB_OK.SetClickHdl( LINK(this, DlgQryJoin, OKClickHdl) );

    aLB_JoinType.SetSelectHdl(LINK(this,DlgQryJoin,LBChangeHdl));

    if ( static_cast<OQueryTableView*>(pParent)->getDesignView()->getController()->isReadOnly() )
    {
        aLB_JoinType.Disable();
        m_pTableControl->Disable();
    }
    else if ( !bFull && !bOuter )
        aLB_JoinType.Disable();
    else
    {
        if ( !bFull )
            aLB_JoinType.RemoveEntry(3);

        if ( !bOuter )
        {
            aLB_JoinType.RemoveEntry(0);
            aLB_JoinType.RemoveEntry(0);
            aLB_JoinType.RemoveEntry(0);
        }

        m_pTableControl->NotifyCellChange();
    }

    FreeResource();
}

//------------------------------------------------------------------------
DlgQryJoin::~DlgQryJoin()
{
    DBG_DTOR(DlgQryJoin,NULL);
    delete m_pTableControl;
    delete m_pConnData;
}
// -----------------------------------------------------------------------------
IMPL_LINK( DlgQryJoin, LBChangeHdl, ListBox*, /*pListBox*/ )
{
    DBG_CHKTHIS(DlgQryJoin,NULL);
    aML_HelpText.SetText(String());

    String sFirstWinName,sSecondWinName;
    USHORT nResId = 0;
    USHORT nPos = aLB_JoinType.GetSelectEntryPos();
    sal_Bool bAddHint = sal_True;
    switch ( nPos )
    {
        default:
        case 0:
            nResId = STR_QUERY_INNER_JOIN;
            bAddHint = sal_False;
            break;
        case 1:
            nResId = STR_QUERY_LEFTRIGHT_JOIN;
            sFirstWinName   = m_pConnData->GetSourceWinName();
            sSecondWinName  = m_pConnData->GetDestWinName();
            break;
        case 2:
        case 3:
            nResId = (nPos == 2) ? STR_QUERY_LEFTRIGHT_JOIN : STR_QUERY_FULL_JOIN;

            sFirstWinName   = m_pConnData->GetDestWinName();
            sSecondWinName  = m_pConnData->GetSourceWinName();
            break;
    }

    String sHelpText = String( ModuleRes( nResId ) );
    if( sFirstWinName.Len() )
    {
        sHelpText.SearchAndReplace( String( RTL_CONSTASCII_STRINGPARAM( "%1" ) ), sFirstWinName );
        sHelpText.SearchAndReplace( String( RTL_CONSTASCII_STRINGPARAM( "%2" ) ), sSecondWinName );
    }
    if ( bAddHint )
    {
        sHelpText += String( RTL_CONSTASCII_STRINGPARAM( "\n" ) );
        sHelpText += String( ModuleRes( STR_JOIN_TYPE_HINT ) );
    }

    aML_HelpText.SetText( sHelpText );
    return 1;
}
// -----------------------------------------------------------------------------

IMPL_LINK( DlgQryJoin, OKClickHdl, Button*, /*pButton*/ )
{
    DBG_CHKTHIS(DlgQryJoin,NULL);
    USHORT nPos = aLB_JoinType.GetSelectEntryPos();
    switch ( nPos )
    {
        case 0:
            eJoinType = INNER_JOIN;
            break;
        case 1:
            eJoinType = LEFT_JOIN;
            break;
        case 2:
            eJoinType = RIGHT_JOIN;
            break;
        case 3:
            eJoinType = FULL_JOIN;
            break;
    }

    m_pConnData->Update();
    m_pOrigConnData->CopyFrom( *m_pConnData );

    EndDialog(RET_OK);
    return 1;
}
// -----------------------------------------------------------------------------
OTableConnectionData* DlgQryJoin::getConnectionData() const
{
    return m_pConnData;
}
// -----------------------------------------------------------------------------
void DlgQryJoin::setValid(sal_Bool _bValid)
{
    LBChangeHdl(&aLB_JoinType);

    aPB_OK.Enable(_bValid);
}
// -----------------------------------------------------------------------------
void DlgQryJoin::notifyConnectionChange( )
{
    setJoinType( m_pConnData->GetJoinType() );
}
// -----------------------------------------------------------------------------
void DlgQryJoin::setJoinType(EJoinType _eNewJoinType)
{
    eJoinType = _eNewJoinType;
    USHORT nPos = 0;
    switch(eJoinType)
    {
        case INNER_JOIN:
            break;
        case LEFT_JOIN:
            nPos = 1;
            break;
        case RIGHT_JOIN:
            nPos = 2;
            break;
        case FULL_JOIN:
            nPos = 3;
            break;
        default:
            break;
    }
    aLB_JoinType.SelectEntryPos(nPos);
    LBChangeHdl(&aLB_JoinType);
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>#include "Var.h"

void *Var::operator new (size_t n, Pool *pool) {
    return pool -> palloc(sizeof(Var));
}

void Var::operator delete(void* ptr, Pool *pool) {
    free(ptr);
}

void Var::get_expression(ostream &out, string wrapEntity, Position position) {
    if (wrapEntity == "App" && position == _right)
        out << ' ';

    out << variable;
}

vector<string> Var::get_tree_view(int shift) {
    vector<string> treeAll;
    treeAll.push_back(string(shift, ' ') + variable);

    return treeAll;
}

Node *Var::reduce(Pool *pool) {
    return this;
}

Node *Var::substitute(Pool *pool, Node *substituteTo, Var *substituteThis) {
    if (this == substituteThis)
        return substituteTo->copy(pool);
    else
        return this;
}

bool Var::is_redex() {
    return false;
}

Var *Var::copy(Pool *pool) {
    return new(pool) Var(variable);
}

<commit_msg>Changed get_tree_view function to print adresses of variables<commit_after>#include "Var.h"
#include <sstream>

void *Var::operator new (size_t n, Pool *pool) {
    return pool -> palloc(sizeof(Var));
}

void Var::operator delete(void* ptr, Pool *pool) {
    free(ptr);
}

void Var::get_expression(ostream &out, string wrapEntity, Position position) {
    if (wrapEntity == "App" && position == _right)
        out << ' ';

    out << variable;
}

vector<string> Var::get_tree_view(int shift) {
    stringstream convert;
    convert << this;

    vector<string> treeAll;
    treeAll.push_back(string(shift, ' ') + variable + ' ' + convert.str() + ' ');

    return treeAll;
}

Node *Var::reduce(Pool *pool) {
    return this;
}

Node *Var::substitute(Pool *pool, Node *substituteTo, Var *substituteThis) {
    if (this == substituteThis)
        return substituteTo->copy(pool);
    else
        return this;
}

bool Var::is_redex() {
    return false;
}

Var *Var::copy(Pool *pool) {
    return new(pool) Var(variable);
}

<|endoftext|>


<commit_before>//===--- Term.cpp - A term in the generics rewrite system -----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/AST/Decl.h"
#include "swift/AST/Types.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <vector>
#include "RewriteContext.h"
#include "Symbol.h"
#include "Term.h"

using namespace swift;
using namespace rewriting;

/// Terms are uniqued and immutable, stored as a single pointer;
/// the Storage type is the allocated backing storage.
struct Term::Storage final
  : public llvm::FoldingSetNode,
    public llvm::TrailingObjects<Storage, Symbol> {
  friend class Symbol;

  unsigned Size;

  explicit Storage(unsigned size) : Size(size) {}

  size_t numTrailingObjects(OverloadToken<Symbol>) const {
    return Size;
  }

  MutableArrayRef<Symbol> getElements() {
    return {getTrailingObjects<Symbol>(), Size};
  }

  ArrayRef<Symbol> getElements() const {
    return {getTrailingObjects<Symbol>(), Size};
  }

  void Profile(llvm::FoldingSetNodeID &id) const;
};

size_t Term::size() const { return Ptr->Size; }

const Symbol *Term::begin() const {
  return Ptr->getElements().begin();
}

const Symbol *Term::end() const {
  return Ptr->getElements().end();
}

std::reverse_iterator<const Symbol *> Term::rbegin() const {
  return Ptr->getElements().rbegin();
}

std::reverse_iterator<const Symbol *> Term::rend() const {
  return Ptr->getElements().rend();
}

Symbol Term::back() const {
  return Ptr->getElements().back();
}

Symbol Term::operator[](size_t index) const {
  return Ptr->getElements()[index];
}

void Term::dump(llvm::raw_ostream &out) const {
  MutableTerm(*this).dump(out);
}

Term Term::get(const MutableTerm &mutableTerm, RewriteContext &ctx) {
  unsigned size = mutableTerm.size();
  assert(size > 0 && "Term must have at least one symbol");

  llvm::FoldingSetNodeID id;
  id.AddInteger(size);
  for (auto symbol : mutableTerm)
    id.AddPointer(symbol.getOpaquePointer());

  void *insertPos = nullptr;
  if (auto *term = ctx.Terms.FindNodeOrInsertPos(id, insertPos))
    return term;

  void *mem = ctx.Allocator.Allocate(
      Storage::totalSizeToAlloc<Symbol>(size),
      alignof(Storage));
  auto *term = new (mem) Storage(size);
  for (unsigned i = 0; i < size; ++i)
    term->getElements()[i] = mutableTerm[i];

  ctx.Terms.InsertNode(term, insertPos);
  ctx.TermHistogram.add(size);

  return term;
}

void Term::Storage::Profile(llvm::FoldingSetNodeID &id) const {
  id.AddInteger(Size);

  for (auto symbol : getElements())
    id.AddPointer(symbol.getOpaquePointer());
}

bool Term::containsUnresolvedSymbols() const {
  for (auto symbol : *this) {
    if (symbol.getKind() == Symbol::Kind::Name)
      return true;
  }

  return false;
}

/// Shortlex order on symbol ranges.
///
/// First we compare length, then perform a lexicographic comparison
/// on symbols if the two ranges have the same length.
///
/// This is used to implement Term::compare() and MutableTerm::compare()
/// below.
static Optional<int>
shortlexCompare(const Symbol *lhsBegin, const Symbol *lhsEnd,
                const Symbol *rhsBegin, const Symbol *rhsEnd,
                RewriteContext &ctx) {
  unsigned lhsSize = (lhsEnd - lhsBegin);
  unsigned rhsSize = (rhsEnd - rhsBegin);
  if (lhsSize != rhsSize)
    return lhsSize < rhsSize ? -1 : 1;

  while (lhsBegin != lhsEnd) {
    auto lhs = *lhsBegin;
    auto rhs = *rhsBegin;

    ++lhsBegin;
    ++rhsBegin;

    Optional<int> result = lhs.compare(rhs, ctx);
    if (!result.hasValue() || *result != 0) {
      assert(lhs != rhs);
      return result;
    }

    assert(lhs == rhs);
  }

  return 0;
}

/// Shortlex order on terms. Returns None if the terms are identical except
/// for an incomparable superclass or concrete type symbol at the end.
Optional<int>
Term::compare(Term other, RewriteContext &ctx) const {
  return shortlexCompare(begin(), end(), other.begin(), other.end(), ctx);
}

/// Shortlex order on mutable terms. Returns None if the terms are identical
/// except for an incomparable superclass or concrete type symbol at the end.
Optional<int>
MutableTerm::compare(const MutableTerm &other, RewriteContext &ctx) const {
  return shortlexCompare(begin(), end(), other.begin(), other.end(), ctx);
}

/// Replace the subterm in the range [from,to) with \p rhs. The subrange must
/// be part of this term itself.
///
/// Note that \p rhs must precede [from,to) in the linear order on terms.
void MutableTerm::rewriteSubTerm(Symbol *from, Symbol *to, Term rhs) {
  auto oldSize = size();
  unsigned lhsLength = (unsigned)(to - from);
  assert(rhs.size() <= lhsLength);

  // Overwrite the occurrence of the left hand side with the
  // right hand side.
  auto newIter = std::copy(rhs.begin(), rhs.end(), from);

  // If the right hand side is shorter than the left hand side,
  // then newIter will point to a location before oldIter, eg
  // if this term is 'T.A.B.C', lhs is 'A.B' and rhs is 'X',
  // then we now have:
  //
  // T.X  .C
  //       ^--- oldIter
  //     ^--- newIter
  //
  // Shift everything over to close the gap (by one location,
  // in this case).
  if (newIter != to) {
    auto newEnd = std::copy(to, end(), newIter);

    // Now, we've moved the gap to the end of the term; close
    // it by shortening the term.
    Symbols.erase(newEnd, end());
  }

  assert(size() == oldSize - lhsLength + rhs.size());
}

void MutableTerm::dump(llvm::raw_ostream &out) const {
  bool first = true;

  for (auto symbol : Symbols) {
    if (!first)
      out << ".";
    else
      first = false;

    symbol.dump(out);
  }
}<commit_msg>RequirementMachine: Allow MutableTerm::rewriteSubTerm() to make the term longer<commit_after>//===--- Term.cpp - A term in the generics rewrite system -----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/AST/Decl.h"
#include "swift/AST/Types.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <vector>
#include "RewriteContext.h"
#include "Symbol.h"
#include "Term.h"

using namespace swift;
using namespace rewriting;

/// Terms are uniqued and immutable, stored as a single pointer;
/// the Storage type is the allocated backing storage.
struct Term::Storage final
  : public llvm::FoldingSetNode,
    public llvm::TrailingObjects<Storage, Symbol> {
  friend class Symbol;

  unsigned Size;

  explicit Storage(unsigned size) : Size(size) {}

  size_t numTrailingObjects(OverloadToken<Symbol>) const {
    return Size;
  }

  MutableArrayRef<Symbol> getElements() {
    return {getTrailingObjects<Symbol>(), Size};
  }

  ArrayRef<Symbol> getElements() const {
    return {getTrailingObjects<Symbol>(), Size};
  }

  void Profile(llvm::FoldingSetNodeID &id) const;
};

size_t Term::size() const { return Ptr->Size; }

const Symbol *Term::begin() const {
  return Ptr->getElements().begin();
}

const Symbol *Term::end() const {
  return Ptr->getElements().end();
}

std::reverse_iterator<const Symbol *> Term::rbegin() const {
  return Ptr->getElements().rbegin();
}

std::reverse_iterator<const Symbol *> Term::rend() const {
  return Ptr->getElements().rend();
}

Symbol Term::back() const {
  return Ptr->getElements().back();
}

Symbol Term::operator[](size_t index) const {
  return Ptr->getElements()[index];
}

void Term::dump(llvm::raw_ostream &out) const {
  MutableTerm(*this).dump(out);
}

Term Term::get(const MutableTerm &mutableTerm, RewriteContext &ctx) {
  unsigned size = mutableTerm.size();
  assert(size > 0 && "Term must have at least one symbol");

  llvm::FoldingSetNodeID id;
  id.AddInteger(size);
  for (auto symbol : mutableTerm)
    id.AddPointer(symbol.getOpaquePointer());

  void *insertPos = nullptr;
  if (auto *term = ctx.Terms.FindNodeOrInsertPos(id, insertPos))
    return term;

  void *mem = ctx.Allocator.Allocate(
      Storage::totalSizeToAlloc<Symbol>(size),
      alignof(Storage));
  auto *term = new (mem) Storage(size);
  for (unsigned i = 0; i < size; ++i)
    term->getElements()[i] = mutableTerm[i];

  ctx.Terms.InsertNode(term, insertPos);
  ctx.TermHistogram.add(size);

  return term;
}

void Term::Storage::Profile(llvm::FoldingSetNodeID &id) const {
  id.AddInteger(Size);

  for (auto symbol : getElements())
    id.AddPointer(symbol.getOpaquePointer());
}

bool Term::containsUnresolvedSymbols() const {
  for (auto symbol : *this) {
    if (symbol.getKind() == Symbol::Kind::Name)
      return true;
  }

  return false;
}

/// Shortlex order on symbol ranges.
///
/// First we compare length, then perform a lexicographic comparison
/// on symbols if the two ranges have the same length.
///
/// This is used to implement Term::compare() and MutableTerm::compare()
/// below.
static Optional<int>
shortlexCompare(const Symbol *lhsBegin, const Symbol *lhsEnd,
                const Symbol *rhsBegin, const Symbol *rhsEnd,
                RewriteContext &ctx) {
  unsigned lhsSize = (lhsEnd - lhsBegin);
  unsigned rhsSize = (rhsEnd - rhsBegin);
  if (lhsSize != rhsSize)
    return lhsSize < rhsSize ? -1 : 1;

  while (lhsBegin != lhsEnd) {
    auto lhs = *lhsBegin;
    auto rhs = *rhsBegin;

    ++lhsBegin;
    ++rhsBegin;

    Optional<int> result = lhs.compare(rhs, ctx);
    if (!result.hasValue() || *result != 0) {
      assert(lhs != rhs);
      return result;
    }

    assert(lhs == rhs);
  }

  return 0;
}

/// Shortlex order on terms. Returns None if the terms are identical except
/// for an incomparable superclass or concrete type symbol at the end.
Optional<int>
Term::compare(Term other, RewriteContext &ctx) const {
  return shortlexCompare(begin(), end(), other.begin(), other.end(), ctx);
}

/// Shortlex order on mutable terms. Returns None if the terms are identical
/// except for an incomparable superclass or concrete type symbol at the end.
Optional<int>
MutableTerm::compare(const MutableTerm &other, RewriteContext &ctx) const {
  return shortlexCompare(begin(), end(), other.begin(), other.end(), ctx);
}

/// Replace the subterm in the range [from,to) of this term with \p rhs.
void MutableTerm::rewriteSubTerm(Symbol *from, Symbol *to, Term rhs) {
  auto oldSize = size();
  unsigned lhsLength = (unsigned)(to - from);

  if (lhsLength == rhs.size()) {
    // Copy the RHS to the LHS.
    auto newTo = std::copy(rhs.begin(), rhs.end(), from);

    // The RHS has the same length as the LHS, so we're done.
    assert(newTo == to);
    (void) newTo;
  } else if (lhsLength > rhs.size()) {
    // Copy the RHS to the LHS.
    auto newTo = std::copy(rhs.begin(), rhs.end(), from);

    // Shorten the term.
    Symbols.erase(newTo, to);
  } else {
    assert(lhsLength < rhs.size());

    // Copy the LHS-sized prefix of RHS to the LHS.
    auto newTo = std::copy(rhs.begin(), rhs.begin() + lhsLength, from);
    assert(newTo == to);

    // Insert the remainder of the RHS term.
    Symbols.insert(to, rhs.begin() + lhsLength, rhs.end());
  }

  assert(size() == oldSize - lhsLength + rhs.size());
}

void MutableTerm::dump(llvm::raw_ostream &out) const {
  bool first = true;

  for (auto symbol : Symbols) {
    if (!first)
      out << ".";
    else
      first = false;

    symbol.dump(out);
  }
}<|endoftext|>


<commit_before>/** \brief Importer for full text documents.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2018 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "FileUtil.h"
#include "FullTextImport.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    std::cerr << "Usage: " << ::progname << " [--verbose] fulltext_file1 [fulltext_file2 .. fulltext_fileN]\n";
    std::exit(EXIT_FAILURE);
}

bool ImportDocument(ControlNumberGuesser &control_number_guesser, const std::string &filename) {
    const auto input(FileUtil::OpenInputFileOrDie(filename));
    FullTextImport::FullTextData full_text_data;
    FullTextImport::ReadExtractedTextFromDisk(input.get(), &full_text_data);

    std::string ppn;
    if (not FullTextImport::CorrelateFullTextData(control_number_guesser, full_text_data, &ppn))
        return false;

    return true;
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc < 2)
        Usage();

    const bool verbose(std::strcmp(argv[1], "--verbose") == 0);
    if (verbose)
        --argc, ++argv;

    if (argc < 2)
        Usage();

    ControlNumberGuesser control_number_guesser;

    unsigned total_count(0), failure_count(0);
    for (int arg_no(1); arg_no < argc; ++arg_no) {
        ++total_count;
        if (not ImportDocument(control_number_guesser, argv[arg_no]))
            ++failure_count;
    }

    LOG_INFO("Failed to import " + std::to_string(failure_count) + " documents of " + std::to_string(total_count) + ".");

    return EXIT_SUCCESS;
}
<commit_msg>Used our Usage library function.<commit_after>/** \brief Importer for full text documents.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2018 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "FileUtil.h"
#include "FullTextImport.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    ::Usage("[--verbose] fulltext_file1 [fulltext_file2 .. fulltext_fileN]");
}

bool ImportDocument(ControlNumberGuesser &control_number_guesser, const std::string &filename) {
    const auto input(FileUtil::OpenInputFileOrDie(filename));
    FullTextImport::FullTextData full_text_data;
    FullTextImport::ReadExtractedTextFromDisk(input.get(), &full_text_data);

    std::string ppn;
    if (not FullTextImport::CorrelateFullTextData(control_number_guesser, full_text_data, &ppn))
        return false;

    return true;
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc < 2)
        Usage();

    const bool verbose(std::strcmp(argv[1], "--verbose") == 0);
    if (verbose)
        --argc, ++argv;

    if (argc < 2)
        Usage();

    ControlNumberGuesser control_number_guesser;

    unsigned total_count(0), failure_count(0);
    for (int arg_no(1); arg_no < argc; ++arg_no) {
        ++total_count;
        if (not ImportDocument(control_number_guesser, argv[arg_no]))
            ++failure_count;
    }

    LOG_INFO("Failed to import " + std::to_string(failure_count) + " documents of " + std::to_string(total_count) + ".");

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>//===-- TargetInstrInfoImpl.cpp - Target Instruction Information ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the TargetInstrInfoImpl class, it just provides default
// implementations of various methods.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
using namespace llvm;

// commuteInstruction - The default implementation of this method just exchanges
// operand 1 and 2.
MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI,
                                                      bool NewMI) const {
  assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() &&
         "This only knows how to commute register operands so far");
  unsigned Reg1 = MI->getOperand(1).getReg();
  unsigned Reg2 = MI->getOperand(2).getReg();
  bool Reg1IsKill = MI->getOperand(1).isKill();
  bool Reg2IsKill = MI->getOperand(2).isKill();
  bool ChangeReg0 = false;
  if (MI->getOperand(0).getReg() == Reg1) {
    // Must be two address instruction!
    assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) &&
           "Expecting a two-address instruction!");
    Reg2IsKill = false;
    ChangeReg0 = true;
  }

  if (NewMI) {
    // Create a new instruction.
    unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg();
    bool Reg0IsDead = MI->getOperand(0).isDead();
    MachineFunction &MF = *MI->getParent()->getParent();
    return BuildMI(MF, MI->getDesc())
      .addReg(Reg0, true, false, false, Reg0IsDead)
      .addReg(Reg2, false, false, Reg2IsKill)
      .addReg(Reg1, false, false, Reg1IsKill);
  }

  if (ChangeReg0)
    MI->getOperand(0).setReg(Reg2);
  MI->getOperand(2).setReg(Reg1);
  MI->getOperand(1).setReg(Reg2);
  MI->getOperand(2).setIsKill(Reg1IsKill);
  MI->getOperand(1).setIsKill(Reg2IsKill);
  return MI;
}

/// CommuteChangesDestination - Return true if commuting the specified
/// instruction will also changes the destination operand. Also return the
/// current operand index of the would be new destination register by
/// reference. This can happen when the commutable instruction is also a
/// two-address instruction.
bool TargetInstrInfoImpl::CommuteChangesDestination(MachineInstr *MI,
                                                    unsigned &OpIdx) const{
  assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() &&
         "This only knows how to commute register operands so far");
  if (MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) {
    // Must be two address instruction!
    assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) &&
           "Expecting a two-address instruction!");
    OpIdx = 2;
    return true;
  }
  return false;
}

bool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI,
                            const SmallVectorImpl<MachineOperand> &Pred) const {
  bool MadeChange = false;
  const TargetInstrDesc &TID = MI->getDesc();
  if (!TID.isPredicable())
    return false;

  for (unsigned j = 0, i = 0, e = MI->getNumOperands(); i != e; ++i) {
    if (TID.OpInfo[i].isPredicate()) {
      MachineOperand &MO = MI->getOperand(i);
      if (MO.isReg()) {
        MO.setReg(Pred[j].getReg());
        MadeChange = true;
      } else if (MO.isImm()) {
        MO.setImm(Pred[j].getImm());
        MadeChange = true;
      } else if (MO.isMBB()) {
        MO.setMBB(Pred[j].getMBB());
        MadeChange = true;
      }
      ++j;
    }
  }
  return MadeChange;
}

void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
                                        MachineBasicBlock::iterator I,
                                        unsigned DestReg,
                                        const MachineInstr *Orig) const {
  MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
  MI->getOperand(0).setReg(DestReg);
  MBB.insert(I, MI);
}

unsigned
TargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const {
  unsigned FnSize = 0;
  for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end();
       MBBI != E; ++MBBI) {
    const MachineBasicBlock &MBB = *MBBI;
    for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end(); I != E; ++I)
      FnSize += GetInstSizeInBytes(I);
  }
  return FnSize;
}
<commit_msg>Fix a 80 column violation.<commit_after>//===-- TargetInstrInfoImpl.cpp - Target Instruction Information ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the TargetInstrInfoImpl class, it just provides default
// implementations of various methods.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
using namespace llvm;

// commuteInstruction - The default implementation of this method just exchanges
// operand 1 and 2.
MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI,
                                                      bool NewMI) const {
  assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() &&
         "This only knows how to commute register operands so far");
  unsigned Reg1 = MI->getOperand(1).getReg();
  unsigned Reg2 = MI->getOperand(2).getReg();
  bool Reg1IsKill = MI->getOperand(1).isKill();
  bool Reg2IsKill = MI->getOperand(2).isKill();
  bool ChangeReg0 = false;
  if (MI->getOperand(0).getReg() == Reg1) {
    // Must be two address instruction!
    assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) &&
           "Expecting a two-address instruction!");
    Reg2IsKill = false;
    ChangeReg0 = true;
  }

  if (NewMI) {
    // Create a new instruction.
    unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg();
    bool Reg0IsDead = MI->getOperand(0).isDead();
    MachineFunction &MF = *MI->getParent()->getParent();
    return BuildMI(MF, MI->getDesc())
      .addReg(Reg0, true, false, false, Reg0IsDead)
      .addReg(Reg2, false, false, Reg2IsKill)
      .addReg(Reg1, false, false, Reg1IsKill);
  }

  if (ChangeReg0)
    MI->getOperand(0).setReg(Reg2);
  MI->getOperand(2).setReg(Reg1);
  MI->getOperand(1).setReg(Reg2);
  MI->getOperand(2).setIsKill(Reg1IsKill);
  MI->getOperand(1).setIsKill(Reg2IsKill);
  return MI;
}

/// CommuteChangesDestination - Return true if commuting the specified
/// instruction will also changes the destination operand. Also return the
/// current operand index of the would be new destination register by
/// reference. This can happen when the commutable instruction is also a
/// two-address instruction.
bool TargetInstrInfoImpl::CommuteChangesDestination(MachineInstr *MI,
                                                    unsigned &OpIdx) const{
  assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() &&
         "This only knows how to commute register operands so far");
  if (MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) {
    // Must be two address instruction!
    assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) &&
           "Expecting a two-address instruction!");
    OpIdx = 2;
    return true;
  }
  return false;
}

bool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI,
                            const SmallVectorImpl<MachineOperand> &Pred) const {
  bool MadeChange = false;
  const TargetInstrDesc &TID = MI->getDesc();
  if (!TID.isPredicable())
    return false;

  for (unsigned j = 0, i = 0, e = MI->getNumOperands(); i != e; ++i) {
    if (TID.OpInfo[i].isPredicate()) {
      MachineOperand &MO = MI->getOperand(i);
      if (MO.isReg()) {
        MO.setReg(Pred[j].getReg());
        MadeChange = true;
      } else if (MO.isImm()) {
        MO.setImm(Pred[j].getImm());
        MadeChange = true;
      } else if (MO.isMBB()) {
        MO.setMBB(Pred[j].getMBB());
        MadeChange = true;
      }
      ++j;
    }
  }
  return MadeChange;
}

void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
                                        MachineBasicBlock::iterator I,
                                        unsigned DestReg,
                                        const MachineInstr *Orig) const {
  MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
  MI->getOperand(0).setReg(DestReg);
  MBB.insert(I, MI);
}

unsigned
TargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const {
  unsigned FnSize = 0;
  for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end();
       MBBI != E; ++MBBI) {
    const MachineBasicBlock &MBB = *MBBI;
    for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end();
         I != E; ++I)
      FnSize += GetInstSizeInBytes(I);
  }
  return FnSize;
}
<|endoftext|>


<commit_before>//===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MCJIT.h"
#include "MCJITMemoryManager.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Target/TargetData.h"

using namespace llvm;

namespace {

static struct RegisterJIT {
  RegisterJIT() { MCJIT::Register(); }
} JITRegistrator;

}

extern "C" void LLVMLinkInMCJIT() {
}

ExecutionEngine *MCJIT::createJIT(Module *M,
                                  std::string *ErrorStr,
                                  JITMemoryManager *JMM,
                                  CodeGenOpt::Level OptLevel,
                                  bool GVsWithCode,
                                  TargetMachine *TM) {
  // Try to register the program as a source of symbols to resolve against.
  //
  // FIXME: Don't do this here.
  sys::DynamicLibrary::LoadLibraryPermanently(0, NULL);

  // If the target supports JIT code generation, create the JIT.
  if (TargetJITInfo *TJ = TM->getJITInfo())
    return new MCJIT(M, TM, *TJ, new MCJITMemoryManager(JMM, M), OptLevel,
                     GVsWithCode);

  if (ErrorStr)
    *ErrorStr = "target does not support JIT code generation";
  return 0;
}

MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
             RTDyldMemoryManager *MM, CodeGenOpt::Level OptLevel,
             bool AllocateGVsWithCode)
  : ExecutionEngine(m), TM(tm), MemMgr(MM), M(m), OS(Buffer), Dyld(MM) {

  PM.add(new TargetData(*TM->getTargetData()));

  // Turn the machine code intermediate representation into bytes in memory
  // that may be executed.
  if (TM->addPassesToEmitMC(PM, Ctx, OS, CodeGenOpt::Default, false)) {
    report_fatal_error("Target does not support MC emission!");
  }

  // Initialize passes.
  // FIXME: When we support multiple modules, we'll want to move the code
  // gen and finalization out of the constructor here and do it more
  // on-demand as part of getPointerToFunction().
  PM.run(*M);
  // Flush the output buffer so the SmallVector gets its data.
  OS.flush();

  // Load the object into the dynamic linker.
  // FIXME: It would be nice to avoid making yet another copy.
  MemoryBuffer *MB = MemoryBuffer::getMemBufferCopy(StringRef(Buffer.data(),
                                                              Buffer.size()));
  if (Dyld.loadObject(MB))
    report_fatal_error(Dyld.getErrorString());
  // Resolve any relocations.
  Dyld.resolveRelocations();
}

MCJIT::~MCJIT() {
  delete MemMgr;
}

void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
  report_fatal_error("not yet implemented");
  return 0;
}

void *MCJIT::getPointerToFunction(Function *F) {
  if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
    bool AbortOnFailure = !F->hasExternalWeakLinkage();
    void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure);
    addGlobalMapping(F, Addr);
    return Addr;
  }

  // FIXME: Should we be using the mangler for this? Probably.
  StringRef BaseName = F->getName();
  if (BaseName[0] == '\1')
    BaseName = BaseName.substr(1);
  else
    Twine Name = TM->getMCAsmInfo()->getGlobalPrefix() + BaseName;
  return (void*)Dyld.getSymbolAddress(Name.str());
}

void *MCJIT::recompileAndRelinkFunction(Function *F) {
  report_fatal_error("not yet implemented");
}

void MCJIT::freeMachineCodeForFunction(Function *F) {
  report_fatal_error("not yet implemented");
}

GenericValue MCJIT::runFunction(Function *F,
                                const std::vector<GenericValue> &ArgValues) {
  assert(F && "Function *F was null at entry to run()");

  void *FPtr = getPointerToFunction(F);
  assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
  const FunctionType *FTy = F->getFunctionType();
  const Type *RetTy = FTy->getReturnType();

  assert((FTy->getNumParams() == ArgValues.size() ||
          (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
         "Wrong number of arguments passed into function!");
  assert(FTy->getNumParams() == ArgValues.size() &&
         "This doesn't support passing arguments through varargs (yet)!");

  // Handle some common cases first.  These cases correspond to common `main'
  // prototypes.
  if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
    switch (ArgValues.size()) {
    case 3:
      if (FTy->getParamType(0)->isIntegerTy(32) &&
          FTy->getParamType(1)->isPointerTy() &&
          FTy->getParamType(2)->isPointerTy()) {
        int (*PF)(int, char **, const char **) =
          (int(*)(int, char **, const char **))(intptr_t)FPtr;

        // Call the function.
        GenericValue rv;
        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
                                 (char **)GVTOP(ArgValues[1]),
                                 (const char **)GVTOP(ArgValues[2])));
        return rv;
      }
      break;
    case 2:
      if (FTy->getParamType(0)->isIntegerTy(32) &&
          FTy->getParamType(1)->isPointerTy()) {
        int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;

        // Call the function.
        GenericValue rv;
        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
                                 (char **)GVTOP(ArgValues[1])));
        return rv;
      }
      break;
    case 1:
      if (FTy->getNumParams() == 1 &&
          FTy->getParamType(0)->isIntegerTy(32)) {
        GenericValue rv;
        int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
        return rv;
      }
      break;
    }
  }

  // Handle cases where no arguments are passed first.
  if (ArgValues.empty()) {
    GenericValue rv;
    switch (RetTy->getTypeID()) {
    default: llvm_unreachable("Unknown return type for function call!");
    case Type::IntegerTyID: {
      unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
      if (BitWidth == 1)
        rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
      else if (BitWidth <= 8)
        rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
      else if (BitWidth <= 16)
        rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
      else if (BitWidth <= 32)
        rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
      else if (BitWidth <= 64)
        rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
      else
        llvm_unreachable("Integer types > 64 bits not supported");
      return rv;
    }
    case Type::VoidTyID:
      rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
      return rv;
    case Type::FloatTyID:
      rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
      return rv;
    case Type::DoubleTyID:
      rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
      return rv;
    case Type::X86_FP80TyID:
    case Type::FP128TyID:
    case Type::PPC_FP128TyID:
      llvm_unreachable("long double not supported yet");
      return rv;
    case Type::PointerTyID:
      return PTOGV(((void*(*)())(intptr_t)FPtr)());
    }
  }

  assert("Full-featured argument passing not supported yet!");
  return GenericValue();
}
<commit_msg>Restore sanity to 131601.<commit_after>//===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MCJIT.h"
#include "MCJITMemoryManager.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Target/TargetData.h"

using namespace llvm;

namespace {

static struct RegisterJIT {
  RegisterJIT() { MCJIT::Register(); }
} JITRegistrator;

}

extern "C" void LLVMLinkInMCJIT() {
}

ExecutionEngine *MCJIT::createJIT(Module *M,
                                  std::string *ErrorStr,
                                  JITMemoryManager *JMM,
                                  CodeGenOpt::Level OptLevel,
                                  bool GVsWithCode,
                                  TargetMachine *TM) {
  // Try to register the program as a source of symbols to resolve against.
  //
  // FIXME: Don't do this here.
  sys::DynamicLibrary::LoadLibraryPermanently(0, NULL);

  // If the target supports JIT code generation, create the JIT.
  if (TargetJITInfo *TJ = TM->getJITInfo())
    return new MCJIT(M, TM, *TJ, new MCJITMemoryManager(JMM, M), OptLevel,
                     GVsWithCode);

  if (ErrorStr)
    *ErrorStr = "target does not support JIT code generation";
  return 0;
}

MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
             RTDyldMemoryManager *MM, CodeGenOpt::Level OptLevel,
             bool AllocateGVsWithCode)
  : ExecutionEngine(m), TM(tm), MemMgr(MM), M(m), OS(Buffer), Dyld(MM) {

  PM.add(new TargetData(*TM->getTargetData()));

  // Turn the machine code intermediate representation into bytes in memory
  // that may be executed.
  if (TM->addPassesToEmitMC(PM, Ctx, OS, CodeGenOpt::Default, false)) {
    report_fatal_error("Target does not support MC emission!");
  }

  // Initialize passes.
  // FIXME: When we support multiple modules, we'll want to move the code
  // gen and finalization out of the constructor here and do it more
  // on-demand as part of getPointerToFunction().
  PM.run(*M);
  // Flush the output buffer so the SmallVector gets its data.
  OS.flush();

  // Load the object into the dynamic linker.
  // FIXME: It would be nice to avoid making yet another copy.
  MemoryBuffer *MB = MemoryBuffer::getMemBufferCopy(StringRef(Buffer.data(),
                                                              Buffer.size()));
  if (Dyld.loadObject(MB))
    report_fatal_error(Dyld.getErrorString());
  // Resolve any relocations.
  Dyld.resolveRelocations();
}

MCJIT::~MCJIT() {
  delete MemMgr;
}

void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
  report_fatal_error("not yet implemented");
  return 0;
}

void *MCJIT::getPointerToFunction(Function *F) {
  if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
    bool AbortOnFailure = !F->hasExternalWeakLinkage();
    void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure);
    addGlobalMapping(F, Addr);
    return Addr;
  }

  // FIXME: Should we be using the mangler for this? Probably.
  StringRef BaseName = F->getName();
  Twine Name;
  if (BaseName[0] == '\1')
    Name = BaseName.substr(1);
  else
    Name = TM->getMCAsmInfo()->getGlobalPrefix() + BaseName;
  return (void*)Dyld.getSymbolAddress(Name.str());
}

void *MCJIT::recompileAndRelinkFunction(Function *F) {
  report_fatal_error("not yet implemented");
}

void MCJIT::freeMachineCodeForFunction(Function *F) {
  report_fatal_error("not yet implemented");
}

GenericValue MCJIT::runFunction(Function *F,
                                const std::vector<GenericValue> &ArgValues) {
  assert(F && "Function *F was null at entry to run()");

  void *FPtr = getPointerToFunction(F);
  assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
  const FunctionType *FTy = F->getFunctionType();
  const Type *RetTy = FTy->getReturnType();

  assert((FTy->getNumParams() == ArgValues.size() ||
          (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
         "Wrong number of arguments passed into function!");
  assert(FTy->getNumParams() == ArgValues.size() &&
         "This doesn't support passing arguments through varargs (yet)!");

  // Handle some common cases first.  These cases correspond to common `main'
  // prototypes.
  if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
    switch (ArgValues.size()) {
    case 3:
      if (FTy->getParamType(0)->isIntegerTy(32) &&
          FTy->getParamType(1)->isPointerTy() &&
          FTy->getParamType(2)->isPointerTy()) {
        int (*PF)(int, char **, const char **) =
          (int(*)(int, char **, const char **))(intptr_t)FPtr;

        // Call the function.
        GenericValue rv;
        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
                                 (char **)GVTOP(ArgValues[1]),
                                 (const char **)GVTOP(ArgValues[2])));
        return rv;
      }
      break;
    case 2:
      if (FTy->getParamType(0)->isIntegerTy(32) &&
          FTy->getParamType(1)->isPointerTy()) {
        int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;

        // Call the function.
        GenericValue rv;
        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
                                 (char **)GVTOP(ArgValues[1])));
        return rv;
      }
      break;
    case 1:
      if (FTy->getNumParams() == 1 &&
          FTy->getParamType(0)->isIntegerTy(32)) {
        GenericValue rv;
        int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
        return rv;
      }
      break;
    }
  }

  // Handle cases where no arguments are passed first.
  if (ArgValues.empty()) {
    GenericValue rv;
    switch (RetTy->getTypeID()) {
    default: llvm_unreachable("Unknown return type for function call!");
    case Type::IntegerTyID: {
      unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
      if (BitWidth == 1)
        rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
      else if (BitWidth <= 8)
        rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
      else if (BitWidth <= 16)
        rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
      else if (BitWidth <= 32)
        rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
      else if (BitWidth <= 64)
        rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
      else
        llvm_unreachable("Integer types > 64 bits not supported");
      return rv;
    }
    case Type::VoidTyID:
      rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
      return rv;
    case Type::FloatTyID:
      rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
      return rv;
    case Type::DoubleTyID:
      rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
      return rv;
    case Type::X86_FP80TyID:
    case Type::FP128TyID:
    case Type::PPC_FP128TyID:
      llvm_unreachable("long double not supported yet");
      return rv;
    case Type::PointerTyID:
      return PTOGV(((void*(*)())(intptr_t)FPtr)());
    }
  }

  assert("Full-featured argument passing not supported yet!");
  return GenericValue();
}
<|endoftext|>