<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include <vector>
#include <utility>
#include <map>
#include <string>

#include <gtest/gtest.h>

#include "jubatus/util/lang/cast.h"

#include "../fv_converter/datum.hpp"
#include "../fv_converter/converter_config.hpp"
#include "../recommender/recommender.hpp"
#include "../recommender/recommender_type.hpp"
#include "../classifier/classifier_test_util.hpp"
#include "../framework/stream_writer.hpp"
#include "recommender.hpp"

#include "test_util.hpp"

using std::string;
using std::map;
using std::vector;
using std::pair;
using std::make_pair;
using std::stringstream;

using jubatus::util::lang::lexical_cast;
using jubatus::core::fv_converter::datum;

namespace jubatus {
namespace core {
namespace driver {

class recommender_test : public ::testing::Test {
 protected:
  void SetUp() {
    recommender_.reset(new driver::recommender(
          jubatus::util::lang::shared_ptr<core::recommender::recommender_base>(
            new core::recommender::inverted_index),
          make_fv_converter()));
  }

  void TearDown() {
    recommender_.reset();
  }

  jubatus::util::lang::shared_ptr<core::driver::recommender> recommender_;
};

TEST_F(recommender_test, small) {
  datum d;
  d.num_values_.push_back(make_pair("f1", 1.0));
  recommender_->update_row("key", d);
  recommender_->clear_row("key");
  recommender_->update_row("key", d);

  recommender_->complete_row_from_datum(d);
  recommender_->complete_row_from_id("key");
}

}  // namespace driver
}  // namespace core
}  // namespace jubatus
<commit_msg>add nearest_neighbor_recommender test<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include <vector>
#include <utility>
#include <map>
#include <string>

#include <gtest/gtest.h>

#include "jubatus/util/lang/cast.h"
#include "jubatus/util/lang/shared_ptr.h"
#include "../common/jsonconfig.hpp"

#include "../fv_converter/datum.hpp"
#include "../fv_converter/converter_config.hpp"
#include "../recommender/recommender.hpp"
#include "../recommender/recommender_type.hpp"
#include "../recommender/recommender_factory.hpp"
#include "../classifier/classifier_test_util.hpp"
#include "../framework/stream_writer.hpp"
#include "recommender.hpp"

#include "test_util.hpp"

using std::string;
using std::map;
using std::vector;
using std::pair;
using std::make_pair;
using std::stringstream;
using jubatus::util::lang::shared_ptr;
using jubatus::util::text::json::json;
using jubatus::util::text::json::json_object;
using jubatus::util::text::json::json_integer;
using jubatus::util::text::json::json_string;
using jubatus::util::text::json::json_float;
using jubatus::util::lang::lexical_cast;
using jubatus::core::fv_converter::datum;
using jubatus::core::recommender::recommender_base;
namespace jubatus {
namespace core {
namespace driver {

class recommender_test : public ::testing::Test {
 protected:
  void SetUp() {
    recommender_.reset(new driver::recommender(
          jubatus::util::lang::shared_ptr<core::recommender::recommender_base>(
            new core::recommender::inverted_index),
          make_fv_converter()));
  }

  void TearDown() {
    recommender_.reset();
  }

  jubatus::util::lang::shared_ptr<core::driver::recommender> recommender_;
};

TEST_F(recommender_test, small) {
  datum d;
  d.num_values_.push_back(make_pair("f1", 1.0));
  recommender_->update_row("key", d);
  recommender_->clear_row("key");
  recommender_->update_row("key", d);

  recommender_->complete_row_from_datum(d);
  recommender_->complete_row_from_id("key");
}

class nn_recommender_test
    : public ::testing::TestWithParam<
        shared_ptr<core::recommender::recommender_base> > {
 protected:
  void SetUp() {
    recommender_.reset(new driver::recommender(
          jubatus::util::lang::shared_ptr<core::recommender::recommender_base>(
            new core::recommender::inverted_index),
          make_tf_idf_fv_converter()));
  }

  void TearDown() {
    recommender_.reset();
  }

  jubatus::util::lang::shared_ptr<core::driver::recommender> recommender_;
};

vector<shared_ptr<recommender_base> >
create_recommender_bases() {
  const std::string id("my_id");
  vector<shared_ptr<recommender_base> > recommenders;

  vector<pair<string, int> > pattern;
  for (size_t i = 8; i < 3000; i = i << 1) {  // up to 2048
    pattern.push_back(make_pair("lsh", i));
    pattern.push_back(make_pair("euclid_lsh", i));
    pattern.push_back(make_pair("minhash", i));
  }
  for (size_t i = 0; i < pattern.size(); ++i) {
    shared_ptr<core::table::column_table> table(new core::table::column_table);

    json jsconf(new json_object);
    json method_param(new json_object);
    method_param["hash_num"] = new json_integer(pattern[i].second);
    jsconf["parameter"] = method_param;
    jsconf["method"] = new json_string(pattern[i].first);
    common::jsonconfig::config conf(jsconf);
    recommenders.push_back(
        core::recommender::recommender_factory::create_recommender(
            "nearest_neighbor_recommender",
            conf,
            id));
  }
  return recommenders;
}

fv_converter::datum create_datum_str(const string& key, const string& value) {
  fv_converter::datum d;
  d.string_values_.push_back(make_pair(key, value));
  return d;
}

TEST_P(nn_recommender_test, update) {
  datum d = create_datum_str("a", "f g h");
  for (int i = 0; i < 10; ++i) {
    recommender_->update_row("id1", create_datum_str("a", "a b c"));
    recommender_->update_row("id2", create_datum_str("a", "d e f"));
    recommender_->update_row("id3", create_datum_str("a", "e f g"));
    recommender_->update_row("id4", create_datum_str("a", "f g h"));
    recommender_->update_row("id5", create_datum_str("a", "h i j"));
    recommender_->update_row("id6", create_datum_str("a", "i j a"));
    recommender_->update_row("id7", create_datum_str("a", "j a b"));
  }

  vector<pair<string, float> > ret = recommender_->similar_row_from_datum(d, 10);
  ASSERT_EQ("id4", ret[0].first);
}

INSTANTIATE_TEST_CASE_P(nn_recommender_test_instance,
    nn_recommender_test,
    testing::ValuesIn(create_recommender_bases()));
}  // namespace driver
}  // namespace core
}  // namespace jubatus
<|endoftext|>


<commit_before>#ifndef STAN__MATH__MATRIX_SPARSE_EXTRACTORS_HPP
#define STAN__MATH__MATRIX_SPARSE_EXTRACTORS_HPP

#include <Eigen/Sparse>
#include <vector>
#include <numeric>

namespace stan {

  namespace math {
    // FIXME: The implementations are the same, only the interpretation
    // differs in CSC vs. CSR.  In the time I had I couldn't get one
    // implementation that swallowed both matrix types.

    /** @defgroup sparse_csc CSC Sparse Extractors.
     *  This group of functions extracts the components of a
     *  Compressed Sparse Column (CSC) sparse matrix.  The components
     *  are:
     *    - w: the non-zero values in the sparse matrix.
     *    - v: one-based row index for each value in w, as a result this
     *      is the same length as w.
     *    - u: one-based index of where each column starts in w, length
     *      is equal to the number of columns plus one.  Last entry is
     *      one-past-the-end in w (one-based...)
     *    - z: number of non-zero entries in each column of w, length is
     *      equal to the number of columns.
     *  @{
     */

    template <typename T>
    const Eigen::Matrix<T, Eigen::Dynamic,1> extract_w(Eigen::SparseMatrix<T> A) {
      Eigen::Matrix<T,Eigen::Dynamic,1> w(A.nonZeros());
      w.setZero();
      for (int j = 0; j < A.nonZeros(); ++j)
        w[j] = *(A.valuePtr()+j);
      return w;
    }

    template <typename T>
    const std::vector<int> extract_v(Eigen::SparseMatrix<T> A) {
      std::vector<int> v(A.nonZeros());
      for (int j = 0; j < A.nonZeros(); ++j)
        v[j] = *(A.innerIndexPtr()+j) + 1;   // make 1-indexed
      return v;
    }

    template <typename T>
    const std::vector<int> extract_u(Eigen::SparseMatrix<T> A) {
      std::vector<int> u(A.outerSize()+1);
      for (int j = 0; j <= A.outerSize(); ++j)
        u[j] = *(A.outerIndexPtr()+j) + 1; // make 1-indexed
      return u;
    }

    template <typename T>
    const std::vector<int> extract_z(Eigen::SparseMatrix<T> A) {
      std::vector<int> u(A.outerSize()+1);
      std::vector<int> z(A.outerSize()+1);
      u = extract_u(A);
      std::adjacent_difference(u.begin(), u.end(), z.begin());
      z.erase(z.begin());
      return z;
    }
    /** @} */ // end of sparse_csc group.

  }
}

#endif
<commit_msg>linted sparse_extractors_csc, no meaningful changes.<commit_after>#ifndef STAN__MATH__MATRIX_SPARSE_EXTRACTORS_HPP
#define STAN__MATH__MATRIX_SPARSE_EXTRACTORS_HPP

#include <Eigen/Sparse>
#include <vector>
#include <numeric>

namespace stan {

  namespace math {
    // FIXME: The implementations are the same, only the interpretation
    // differs in CSC vs. CSR.  In the time I had I couldn't get one
    // implementation that swallowed both matrix types.

    /** @defgroup sparse_csc CSC Sparse Extractors.
     *  This group of functions extracts the components of a
     *  Compressed Sparse Column (CSC) sparse matrix.  The components
     *  are:
     *    - w: the non-zero values in the sparse matrix.
     *    - v: one-based row index for each value in w, as a result this
     *      is the same length as w.
     *    - u: one-based index of where each column starts in w, length
     *      is equal to the number of columns plus one.  Last entry is
     *      one-past-the-end in w (one-based...)
     *    - z: number of non-zero entries in each column of w, length is
     *      equal to the number of columns.
     *  @{
     */

    template <typename T>
    const Eigen::Matrix<T, Eigen::Dynamic, 1>
    extract_w(Eigen::SparseMatrix<T> A) {
      Eigen::Matrix<T, Eigen::Dynamic, 1> w(A.nonZeros());
      w.setZero();
      for (int j = 0; j < A.nonZeros(); ++j)
        w[j] = *(A.valuePtr()+j);
      return w;
    }

    template <typename T>
    const std::vector<int> extract_v(Eigen::SparseMatrix<T> A) {
      std::vector<int> v(A.nonZeros());
      for (int j = 0; j < A.nonZeros(); ++j)
        v[j] = *(A.innerIndexPtr()+j) + 1;   // make 1-indexed
      return v;
    }

    template <typename T>
    const std::vector<int> extract_u(Eigen::SparseMatrix<T> A) {
      std::vector<int> u(A.outerSize()+1);
      for (int j = 0; j <= A.outerSize(); ++j)
        u[j] = *(A.outerIndexPtr()+j) + 1;   // make 1-indexed
      return u;
    }

    template <typename T>
    const std::vector<int> extract_z(Eigen::SparseMatrix<T> A) {
      std::vector<int> u(A.outerSize()+1);
      std::vector<int> z(A.outerSize()+1);
      u = extract_u(A);
      std::adjacent_difference(u.begin(), u.end(), z.begin());
      z.erase(z.begin());
      return z;
    }
    /** @} */   // end of sparse_csc group.

  }
}

#endif
<|endoftext|>


<commit_before>// Time:  O(N^2)
// Space: O(N)

class Solution {
public:
    /**
     * @param A an integer array
     * @return a long integer
     */
    long long permutationIndexII(vector<int>& A) {
        long long index = 1;
        // Position 1 is paired with factor 0 and so is skipped.
        int position = 2;
        long long factor = 1;
        map<int, int> number_to_count;
        ++number_to_count[A.back()];
        for (int i = static_cast<int>(A.size()) - 2; i >= 0; --i) {
            ++number_to_count[A[i]];
            for (const auto& kvp : number_to_count) {
                if (kvp.first >= A[i]) {
                    break;
                }
                index += factor * kvp.second / number_to_count[A[i]];
            }
            factor = factor * position / number_to_count[A[i]];
            ++position;
        }
        return index;
    }
};

// Time:  O(N^2)
// Space: O(N)
class Solution2 {
public:
    /**
     * @param A an integer array
     * @return a long integer
     */
    long long permutationIndexII(vector<int>& A) {
        long long index = 1;
        // Position 1 is paired with factor 0 and so is skipped.
        int position = 2;
        long long factor = 1;
        unordered_map<int, int> number_to_count;
        ++number_to_count[A.back()];
        for (int i = static_cast<int>(A.size()) - 2; i >= 0; --i) {
            unordered_map<int, int> successor_to_count;
            ++number_to_count[A[i]];
            for (int j = i + 1; j < A.size(); ++j) {
                if (A[i] > A[j]) {
                    ++successor_to_count[A[j]];
                }
            }
            for (const auto& kvp : successor_to_count) {
                index += factor * kvp.second / number_to_count[A[i]];
            }
            factor = factor * position / number_to_count[A[i]];
            ++position;
        }
        return index;
    }
};

// Time:  O(N^3)
// Space: O(N)
class Solution3 {
public:
    /**
     * @param A an integer array
     * @return a long integer
     */
    long long permutationIndexII(vector<int>& A) {
        long long index = 1;
        unordered_map<int, int> number_to_count;
        ++number_to_count[A.back()];
        for (int i = static_cast<int>(A.size()) - 2; i >= 0; --i) {
            unordered_map<int, int> successor_to_count;
            ++number_to_count[A[i]];
            for (int j = i + 1; j < A.size(); ++j) {
                if (A[i] > A[j]) {
                    ++successor_to_count[A[j]];
                }
            }
            for (const auto& kvp : successor_to_count) {
                --number_to_count[kvp.first];
                index += combination(number_to_count);
                ++number_to_count[kvp.first];
            }
        }
        return index;
    }

    long long combination(const unordered_map<int, int>& number_to_count) {
        int n = 0;
        for (const auto& kvp : number_to_count) {
            n += kvp.second;
        }
        long long count = 1;
        for (const auto& kvp : number_to_count) {
            // C(n, k) = (n) / 1 * (n - 1) / 2 ... * (n - k + 1) / k
            for (int i = 1; i <= kvp.second; ++i, --n) {
                 count = count * n / i;
            }
        }

        return count;
    }
};
<commit_msg>Update permutation-index-ii.cpp<commit_after>// Time:  O(n^2)
// Space: O(n)

class Solution {
public:
    /**
     * @param A an integer array
     * @return a long integer
     */
    long long permutationIndexII(vector<int>& A) {
        long long index = 1;
        // Position 1 is paired with factor 0 and so is skipped.
        int position = 2;
        long long factor = 1;
        map<int, int> number_to_count;
        ++number_to_count[A.back()];
        for (int i = static_cast<int>(A.size()) - 2; i >= 0; --i) {
            ++number_to_count[A[i]];
            for (const auto& kvp : number_to_count) {
                if (kvp.first >= A[i]) {
                    break;
                }
                index += factor * kvp.second / number_to_count[A[i]];
            }
            factor = factor * position / number_to_count[A[i]];
            ++position;
        }
        return index;
    }
};

// Time:  O(n^2)
// Space: O(n)
class Solution2 {
public:
    /**
     * @param A an integer array
     * @return a long integer
     */
    long long permutationIndexII(vector<int>& A) {
        long long index = 1;
        // Position 1 is paired with factor 0 and so is skipped.
        int position = 2;
        long long factor = 1;
        unordered_map<int, int> number_to_count;
        ++number_to_count[A.back()];
        for (int i = static_cast<int>(A.size()) - 2; i >= 0; --i) {
            unordered_map<int, int> successor_to_count;
            ++number_to_count[A[i]];
            for (int j = i + 1; j < A.size(); ++j) {
                if (A[i] > A[j]) {
                    ++successor_to_count[A[j]];
                }
            }
            for (const auto& kvp : successor_to_count) {
                index += factor * kvp.second / number_to_count[A[i]];
            }
            factor = factor * position / number_to_count[A[i]];
            ++position;
        }
        return index;
    }
};

// Time:  O(n^3)
// Space: O(n)
class Solution3 {
public:
    /**
     * @param A an integer array
     * @return a long integer
     */
    long long permutationIndexII(vector<int>& A) {
        long long index = 1;
        unordered_map<int, int> number_to_count;
        ++number_to_count[A.back()];
        for (int i = static_cast<int>(A.size()) - 2; i >= 0; --i) {
            unordered_map<int, int> successor_to_count;
            ++number_to_count[A[i]];
            for (int j = i + 1; j < A.size(); ++j) {
                if (A[i] > A[j]) {
                    ++successor_to_count[A[j]];
                }
            }
            for (const auto& kvp : successor_to_count) {
                --number_to_count[kvp.first];
                index += combination(number_to_count);
                ++number_to_count[kvp.first];
            }
        }
        return index;
    }

    long long combination(const unordered_map<int, int>& number_to_count) {
        int n = 0;
        for (const auto& kvp : number_to_count) {
            n += kvp.second;
        }
        long long count = 1;
        for (const auto& kvp : number_to_count) {
            // C(n, k) = (n) / 1 * (n - 1) / 2 ... * (n - k + 1) / k
            for (int i = 1; i <= kvp.second; ++i, --n) {
                 count = count * n / i;
            }
        }

        return count;
    }
};
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2003 Unai Garro <ugarro@users.sourceforge.net>
 */

#include "pref.h"
#include "krecipes.h"
#include "krecipesview.h"
#include "dialogs/recipeinputdialog.h"
#include "dialogs/selectrecipedialog.h"
#include "dialogs/ingredientsdialog.h"
#include "dialogs/propertiesdialog.h"
#include "dialogs/shoppinglistdialog.h"
#include "dialogs/categorieseditordialog.h"
#include "dialogs/authorsdialog.h"
#include "dialogs/unitsdialog.h"

#include "gui/pagesetupdialog.h"

#include "importers/kreimporter.h"
#include "importers/mmfimporter.h"
#include "importers/mx2importer.h"
#include "importers/mxpimporter.h"
#include "importers/nycgenericimporter.h"
#include "importers/recipemlimporter.h"

#include "recipe.h"
#include "DBBackend/recipedb.h"

#include <qdragobject.h>
#include <kprinter.h>
#include <qpainter.h>
#include <qpaintdevicemetrics.h>
#include <qmessagebox.h>

#include <kprogress.h>
#include <kmessagebox.h>
#include <kglobal.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kmenubar.h>
#include <kstatusbar.h>
#include <kkeydialog.h>
#include <kaccel.h>
#include <kio/netaccess.h>
#include <kfiledialog.h>
#include <kconfig.h>

#include <kedittoolbar.h>
#include <kstdaccel.h>
#include <kaction.h>
#include <kstdaction.h>
//Settings headers
#include <kdeversion.h>
#if defined(KDE_MAKE_VERSION)
  # if KDE_VERSION > KDE_MAKE_VERSION(3,1,4)
     #include <kautoconfigdialog.h>
  # endif
#endif

#include "serverprefs.h"
#include "unitsprefs.h"
#include "importprefs.h"

Krecipes::Krecipes()
    : KMainWindow( 0, "Krecipes" ),
      m_view(new KrecipesView(this)),
      m_printer(0)
{

    // accept dnd
    setAcceptDrops(true);

    // tell the KMainWindow that this is indeed the main widget
    setCentralWidget(m_view);

    // then, setup our actions
    setupActions();

    // and a status bar
    statusBar()->show();

    // apply the saved mainwindow settings, if any, and ask the mainwindow
    // to automatically save settings if changed: window size, toolbar
    // position, icon size, etc.
    setAutoSaveSettings();

    // Resize if the window is too small so the buttons are shown
    QSize wsize=size();
    if (wsize.width()<640)
    	{
	wsize.setWidth(640);
	resize(wsize);
	}

    // allow the view to change the statusbar and caption
    connect(m_view, SIGNAL(signalChangeStatusbar(const QString&)),
            this,   SLOT(changeStatusbar(const QString&)));
    connect(m_view, SIGNAL(signalChangeCaption(const QString&)),
            this,   SLOT(changeCaption(const QString&)));

    // Enable/Disable the Save Button (Initialize disabled, and connect signal)

    connect(this->m_view, SIGNAL(enableSaveOption(bool)), this, SLOT(enableSaveOption(bool)));
    enableSaveOption(false); // Disables saving initially

    // Enable/Disable the SaveAs Button (Initialize disabled, and connect signal)

    connect(this->m_view->selectPanel, SIGNAL(recipeSelected(bool)), saveAsAction, SLOT(setEnabled(bool)));

    parsing_file_dlg = new KDialog(this,"parsing_file_dlg",true,Qt::WX11BypassWM);
    QLabel *parsing_file_dlg_label = new QLabel(i18n("Gathering recipe data from file.\nPlease wait..."),parsing_file_dlg);
    parsing_file_dlg_label->setFrameStyle( QFrame::Box | QFrame::Raised );
    (new QVBoxLayout(parsing_file_dlg))->addWidget( parsing_file_dlg_label );
    parsing_file_dlg->adjustSize();
    //parsing_file_dlg->setFixedSize(parsing_file_dlg->size());
}

Krecipes::~Krecipes()
{
}

void Krecipes::setupActions()
{
    KStdAction::openNew(this, SLOT(fileNew()), actionCollection());
    KStdAction::open(this, SLOT(fileOpen()), actionCollection());
    saveAction=KStdAction::save(this, SLOT(fileSave()), actionCollection());
    saveAsAction=KStdAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
    saveAsAction->setEnabled(false);
    KStdAction::print(this, SLOT(filePrint()), actionCollection());
    KStdAction::quit(kapp, SLOT(quit()), actionCollection());

    m_toolbarAction = KStdAction::showToolbar(this, SLOT(optionsShowToolbar()), actionCollection());
    m_statusbarAction = KStdAction::showStatusbar(this, SLOT(optionsShowStatusbar()), actionCollection());

    KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
    KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection());
    KStdAction::preferences(this, SLOT(optionsPreferences()), actionCollection());

    (void)new KAction(i18n("Import..."), CTRL+Key_I,
                                  this, SLOT(import()),
                                  actionCollection(), "import_action");

    (void)new KAction(i18n("Page Setup..."), 0,
                                  this, SLOT(pageSetupSlot()),
                                  actionCollection(), "page_setup_action");

    createGUI();
}

void Krecipes::saveProperties(KConfig *)
{
    // the 'config' object points to the session managed
    // config file.  anything you write here will be available
    // later when this app is restored

    //if (!m_view->currentURL().isNull())
      //  config->writeEntry("lastURL", m_view->currentURL());
}

void Krecipes::readProperties(KConfig *)
{
    // the 'config' object points to the session managed
    // config file.  this function is automatically called whenever
    // the app is being restored.  read in here whatever you wrote
    // in 'saveProperties'

    //QString url = config->readEntry("lastURL");

    //if (!url.isNull())
      //  m_view->openURL(KURL(url));
}

void Krecipes::dragEnterEvent(QDragEnterEvent *event)
{
    // accept uri drops only
    event->accept(QUriDrag::canDecode(event));
}

void Krecipes::fileNew()
{

    // Create a new element (Element depends on active panel. New recipe by default)
    m_view->createNewElement();
}

void Krecipes::fileOpen()
{
    // this slot is called whenever the File->Open menu is selected,
    // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar
    // button is clicked
/*
    // this brings up the generic open dialog
    KURL url = KURLRequesterDlg::getURL(QString::null, this, i18n("Open Location") );
*/
    // standard filedialog
    /*KURL url = KFileDialog::getOpenURL(QString::null, QString::null, this, i18n("Open Location"));
    if (!url.isEmpty())
        m_view->openURL(url);*/
}

void Krecipes::fileSave()
{
    // this slot is called whenever the File->Save menu is selected,
    // the Save shortcut is pressed (usually CTRL+S) or the Save toolbar
    // button is clicked
m_view->save();
}

void Krecipes::fileSaveAs()
{
       // this slot is called whenever the File->Save As menu is selected,
	m_view->exportRecipe();
}

void Krecipes::filePrint()
{
	m_view->print();
}

void Krecipes::import()
{
	KFileDialog file_dialog( QString::null,
	  "*.kre *.kreml|Krecipes (*.kre, *.kreml)\n"
	  "*.mx2|MasterCook (*.mx2)\n"
	  "*.mxp *.txt|MasterCook Export (*.mxp, *.txt)\n"
	  "*.mmf *.txt|Meal-Master Format (*.mmf, *.txt)\n"
	  "*.txt|\"Now You're Cooking\" Generic Export (*.txt)\n"
	  "*.xml *.recipeml|RecipeML (*.xml, *.recipeml)",
	  this,
	  "file_dialog",
	  true
	);
	file_dialog.setMode( KFile::Files );

	if ( file_dialog.exec() == KFileDialog::Accepted )
	{
		QStringList warnings_list;

		QString selected_filter = file_dialog.currentFilter();
		QStringList files = file_dialog.selectedFiles();

		for ( QStringList::const_iterator it = files.begin(); it != files.end(); ++it )
		{
			parsing_file_dlg->show();

			BaseImporter *importer;
			if ( selected_filter == "*.mxp *.txt" )
				importer = new MXPImporter( *it );
			else if ( selected_filter == "*.mmf *.txt" )
				importer = new MMFImporter( *it );
			else if ( selected_filter == "*.txt" )
				importer = new NYCGenericImporter( *it );
			else if ( selected_filter == "*.mx2" )
				importer = new MX2Importer( *it );
			else if ( selected_filter == "*.kre *.kreml" )
				importer = new KreImporter( *it );
			else if ( selected_filter == "*.xml *.recipeml" )
				importer = new RecipeMLImporter( *it );
			else
			{
				KMessageBox::sorry( this,
				  QString(i18n("Filter \"%1\" not recognized.\n"
				    "Please select one of the provided filters.")).arg(selected_filter),
				  i18n("Unrecognized Filter")
				);
				parsing_file_dlg->hide();
				import(); //let's try again :)
				return;
			}

			parsing_file_dlg->hide();

			QString error = importer->getErrorMsg();
			if ( !error.isNull() )
				KMessageBox::error( this, QString(i18n("Error importing file %1\n%2")).arg(*it).arg(error) );
			else
				m_view->import( *importer );

			if ( importer->getWarningMsgs().count() > 0 )
			{
				warnings_list += QString(i18n("The file \"%1\" generated the following warnings:")).arg(*it);
				warnings_list += importer->getWarningMsgs();
			}

			delete importer;
		}

		if ( warnings_list.count() > 0 )
		{
			warnings_list.prepend(i18n("NOTE: We recommend that all recipes generating warnings be checked to ensure that they were properly imported, and no loss of recipe data has occured."));

			KTextEdit *warningEdit = new KTextEdit( this );
			warningEdit->setText( warnings_list.join("\n\n") );
			warningEdit->setReadOnly(true);

			KDialogBase showWarningsDlg( KDialogBase::Swallow, i18n("Import warnings"), KDialogBase::Ok, KDialogBase::Default, this );
			showWarningsDlg.setMainWidget( warningEdit ); //KDialogBase will delete warningEdit for us
			showWarningsDlg.resize( QSize(550,250) );
			showWarningsDlg.exec();
		}

		//TODO: to just reload the active panel would be preferable
		m_view->selectPanel->reload();
		m_view->ingredientsPanel->reload();
		m_view->propertiesPanel->reload();
		m_view->unitsPanel->reload();
		m_view->shoppingListPanel->reload();
		m_view->categoriesPanel->reload();
		m_view->authorsPanel->reload();
	}
}

void Krecipes::pageSetupSlot()
{
	Recipe recipe;
	m_view->selectPanel->getCurrentRecipe(&recipe);

	PageSetupDialog *page_setup = new PageSetupDialog(this,recipe);
	page_setup->exec();

	delete page_setup;
}

//return true to close app
bool Krecipes::queryClose()
{
	if ( !m_view->inputPanel->everythingSaved() )
	{
		switch( KMessageBox::questionYesNoCancel( this,
		  i18n("A recipe contains unsaved changes.\n"
		  "Do you want to save the changes before exiting?"),
		  i18n("Unsaved Changes") ) )
		{
		case KMessageBox::Yes: m_view->save();
		case KMessageBox::No: return true;
		case KMessageBox::Cancel: return false;
		default: return true;
		}
	}
	else
		return true;
}

void Krecipes::optionsShowToolbar()
{
    // this is all very cut and paste code for showing/hiding the
    // toolbar
    if (m_toolbarAction->isChecked())
        toolBar()->show();
    else
        toolBar()->hide();
}

void Krecipes::optionsShowStatusbar()
{
    // this is all very cut and paste code for showing/hiding the
    // statusbar
    if (m_statusbarAction->isChecked())
        statusBar()->show();
    else
        statusBar()->hide();
}

void Krecipes::optionsConfigureKeys()
{
#if defined(KDE_MAKE_VERSION)
# if KDE_VERSION > KDE_MAKE_VERSION(3,1,4)
   // for KDE 3.2: KKeyDialog::configureKeys is deprecated
   KKeyDialog::configure(actionCollection(), this, true);
 #else
    KKeyDialog::configureKeys(actionCollection(), "krecipesui.rc");
#endif
 #else
  KKeyDialog::configureKeys(actionCollection(), "krecipesui.rc");
#endif
}

void Krecipes::optionsConfigureToolbars()
{
    // use the standard toolbar editor
#if defined(KDE_MAKE_VERSION)
# if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0)
    saveMainWindowSettings(KGlobal::config(), autoSaveGroup());
# else
    saveMainWindowSettings(KGlobal::config());
# endif
#else
    saveMainWindowSettings(KGlobal::config());
#endif
    KEditToolbar dlg(actionCollection());
    connect(&dlg, SIGNAL(newToolbarConfig()), this, SLOT(newToolbarConfig()));
    dlg.exec();
}

void Krecipes::newToolbarConfig()
{
    // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
    // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
    createGUI();

#if defined(KDE_MAKE_VERSION)
# if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0)
    applyMainWindowSettings(KGlobal::config(), autoSaveGroup());
# else
    applyMainWindowSettings(KGlobal::config());
# endif
#else
    applyMainWindowSettings(KGlobal::config());
#endif
}

void Krecipes::optionsPreferences()
{
#if defined(KDE_MAKE_VERSION)
# if KDE_VERSION > KDE_MAKE_VERSION(3,1,4)
     if(KAutoConfigDialog::showDialog("settings"))
		return;

    KAutoConfigDialog *dialog = new KAutoConfigDialog(this, "settings");
    dialog->addPage(new serverprefs(0, "serverprefs"), i18n("Server Settings"), "Server", "identity", i18n("Database Server Options"));
    dialog->addPage(new unitsprefs(0, "NumberFormat"), i18n("Units"), "Units", "frac", i18n("Customize Units"));
    dialog->addPage(new importprefs(0, "Import"), i18n("Units"), "Import", "redo", i18n("Recipe Import Options"));
    //connect(dialog, SIGNAL(settingsChanged()), this, SLOT(loadSettings()));
    dialog->show();
# else
   // popup some sort of preference dialog, here
    KrecipesPreferences dlg(this);
    if (dlg.exec())
    {}
# endif
#else
      // popup some sort of preference dialog, here
    KrecipesPreferences dlg(this);
    if (dlg.exec())
    {}
#endif
}

void Krecipes::changeStatusbar(const QString& text)
{
    // display the text on the statusbar
    statusBar()->message(text);
}

void Krecipes::changeCaption(const QString& text)
{
    // display the text on the caption
    setCaption(text);
}
void Krecipes::enableSaveOption(bool en)
{
saveAction->setEnabled(en);
}

#include "krecipes.moc"
<commit_msg>use a better method to filter versions. 3.1.5 will not have KAutoConfigDialog stuff in....<commit_after>/*
 * Copyright (C) 2003 Unai Garro <ugarro@users.sourceforge.net>
 */

#include "pref.h"
#include "krecipes.h"
#include "krecipesview.h"
#include "dialogs/recipeinputdialog.h"
#include "dialogs/selectrecipedialog.h"
#include "dialogs/ingredientsdialog.h"
#include "dialogs/propertiesdialog.h"
#include "dialogs/shoppinglistdialog.h"
#include "dialogs/categorieseditordialog.h"
#include "dialogs/authorsdialog.h"
#include "dialogs/unitsdialog.h"

#include "gui/pagesetupdialog.h"

#include "importers/kreimporter.h"
#include "importers/mmfimporter.h"
#include "importers/mx2importer.h"
#include "importers/mxpimporter.h"
#include "importers/nycgenericimporter.h"
#include "importers/recipemlimporter.h"

#include "recipe.h"
#include "DBBackend/recipedb.h"

#include <qdragobject.h>
#include <kprinter.h>
#include <qpainter.h>
#include <qpaintdevicemetrics.h>
#include <qmessagebox.h>

#include <kprogress.h>
#include <kmessagebox.h>
#include <kglobal.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kmenubar.h>
#include <kstatusbar.h>
#include <kkeydialog.h>
#include <kaccel.h>
#include <kio/netaccess.h>
#include <kfiledialog.h>
#include <kconfig.h>

#include <kedittoolbar.h>
#include <kstdaccel.h>
#include <kaction.h>
#include <kstdaction.h>
//Settings headers
#include <kdeversion.h>
#if defined(KDE_MAKE_VERSION)
  # if KDE_VERSION > KDE_MAKE_VERSION(3,1,4)
     #include <kautoconfigdialog.h>
  # endif
#endif

#include "serverprefs.h"
#include "unitsprefs.h"
#include "importprefs.h"

Krecipes::Krecipes()
    : KMainWindow( 0, "Krecipes" ),
      m_view(new KrecipesView(this)),
      m_printer(0)
{

    // accept dnd
    setAcceptDrops(true);

    // tell the KMainWindow that this is indeed the main widget
    setCentralWidget(m_view);

    // then, setup our actions
    setupActions();

    // and a status bar
    statusBar()->show();

    // apply the saved mainwindow settings, if any, and ask the mainwindow
    // to automatically save settings if changed: window size, toolbar
    // position, icon size, etc.
    setAutoSaveSettings();

    // Resize if the window is too small so the buttons are shown
    QSize wsize=size();
    if (wsize.width()<640)
    	{
	wsize.setWidth(640);
	resize(wsize);
	}

    // allow the view to change the statusbar and caption
    connect(m_view, SIGNAL(signalChangeStatusbar(const QString&)),
            this,   SLOT(changeStatusbar(const QString&)));
    connect(m_view, SIGNAL(signalChangeCaption(const QString&)),
            this,   SLOT(changeCaption(const QString&)));

    // Enable/Disable the Save Button (Initialize disabled, and connect signal)

    connect(this->m_view, SIGNAL(enableSaveOption(bool)), this, SLOT(enableSaveOption(bool)));
    enableSaveOption(false); // Disables saving initially

    // Enable/Disable the SaveAs Button (Initialize disabled, and connect signal)

    connect(this->m_view->selectPanel, SIGNAL(recipeSelected(bool)), saveAsAction, SLOT(setEnabled(bool)));

    parsing_file_dlg = new KDialog(this,"parsing_file_dlg",true,Qt::WX11BypassWM);
    QLabel *parsing_file_dlg_label = new QLabel(i18n("Gathering recipe data from file.\nPlease wait..."),parsing_file_dlg);
    parsing_file_dlg_label->setFrameStyle( QFrame::Box | QFrame::Raised );
    (new QVBoxLayout(parsing_file_dlg))->addWidget( parsing_file_dlg_label );
    parsing_file_dlg->adjustSize();
    //parsing_file_dlg->setFixedSize(parsing_file_dlg->size());
}

Krecipes::~Krecipes()
{
}

void Krecipes::setupActions()
{
    KStdAction::openNew(this, SLOT(fileNew()), actionCollection());
    KStdAction::open(this, SLOT(fileOpen()), actionCollection());
    saveAction=KStdAction::save(this, SLOT(fileSave()), actionCollection());
    saveAsAction=KStdAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
    saveAsAction->setEnabled(false);
    KStdAction::print(this, SLOT(filePrint()), actionCollection());
    KStdAction::quit(kapp, SLOT(quit()), actionCollection());

    m_toolbarAction = KStdAction::showToolbar(this, SLOT(optionsShowToolbar()), actionCollection());
    m_statusbarAction = KStdAction::showStatusbar(this, SLOT(optionsShowStatusbar()), actionCollection());

    KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
    KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection());
    KStdAction::preferences(this, SLOT(optionsPreferences()), actionCollection());

    (void)new KAction(i18n("Import..."), CTRL+Key_I,
                                  this, SLOT(import()),
                                  actionCollection(), "import_action");

    (void)new KAction(i18n("Page Setup..."), 0,
                                  this, SLOT(pageSetupSlot()),
                                  actionCollection(), "page_setup_action");

    createGUI();
}

void Krecipes::saveProperties(KConfig *)
{
    // the 'config' object points to the session managed
    // config file.  anything you write here will be available
    // later when this app is restored

    //if (!m_view->currentURL().isNull())
      //  config->writeEntry("lastURL", m_view->currentURL());
}

void Krecipes::readProperties(KConfig *)
{
    // the 'config' object points to the session managed
    // config file.  this function is automatically called whenever
    // the app is being restored.  read in here whatever you wrote
    // in 'saveProperties'

    //QString url = config->readEntry("lastURL");

    //if (!url.isNull())
      //  m_view->openURL(KURL(url));
}

void Krecipes::dragEnterEvent(QDragEnterEvent *event)
{
    // accept uri drops only
    event->accept(QUriDrag::canDecode(event));
}

void Krecipes::fileNew()
{

    // Create a new element (Element depends on active panel. New recipe by default)
    m_view->createNewElement();
}

void Krecipes::fileOpen()
{
    // this slot is called whenever the File->Open menu is selected,
    // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar
    // button is clicked
/*
    // this brings up the generic open dialog
    KURL url = KURLRequesterDlg::getURL(QString::null, this, i18n("Open Location") );
*/
    // standard filedialog
    /*KURL url = KFileDialog::getOpenURL(QString::null, QString::null, this, i18n("Open Location"));
    if (!url.isEmpty())
        m_view->openURL(url);*/
}

void Krecipes::fileSave()
{
    // this slot is called whenever the File->Save menu is selected,
    // the Save shortcut is pressed (usually CTRL+S) or the Save toolbar
    // button is clicked
m_view->save();
}

void Krecipes::fileSaveAs()
{
       // this slot is called whenever the File->Save As menu is selected,
	m_view->exportRecipe();
}

void Krecipes::filePrint()
{
	m_view->print();
}

void Krecipes::import()
{
	KFileDialog file_dialog( QString::null,
	  "*.kre *.kreml|Krecipes (*.kre, *.kreml)\n"
	  "*.mx2|MasterCook (*.mx2)\n"
	  "*.mxp *.txt|MasterCook Export (*.mxp, *.txt)\n"
	  "*.mmf *.txt|Meal-Master Format (*.mmf, *.txt)\n"
	  "*.txt|\"Now You're Cooking\" Generic Export (*.txt)\n"
	  "*.xml *.recipeml|RecipeML (*.xml, *.recipeml)",
	  this,
	  "file_dialog",
	  true
	);
	file_dialog.setMode( KFile::Files );

	if ( file_dialog.exec() == KFileDialog::Accepted )
	{
		QStringList warnings_list;

		QString selected_filter = file_dialog.currentFilter();
		QStringList files = file_dialog.selectedFiles();

		for ( QStringList::const_iterator it = files.begin(); it != files.end(); ++it )
		{
			parsing_file_dlg->show();

			BaseImporter *importer;
			if ( selected_filter == "*.mxp *.txt" )
				importer = new MXPImporter( *it );
			else if ( selected_filter == "*.mmf *.txt" )
				importer = new MMFImporter( *it );
			else if ( selected_filter == "*.txt" )
				importer = new NYCGenericImporter( *it );
			else if ( selected_filter == "*.mx2" )
				importer = new MX2Importer( *it );
			else if ( selected_filter == "*.kre *.kreml" )
				importer = new KreImporter( *it );
			else if ( selected_filter == "*.xml *.recipeml" )
				importer = new RecipeMLImporter( *it );
			else
			{
				KMessageBox::sorry( this,
				  QString(i18n("Filter \"%1\" not recognized.\n"
				    "Please select one of the provided filters.")).arg(selected_filter),
				  i18n("Unrecognized Filter")
				);
				parsing_file_dlg->hide();
				import(); //let's try again :)
				return;
			}

			parsing_file_dlg->hide();

			QString error = importer->getErrorMsg();
			if ( !error.isNull() )
				KMessageBox::error( this, QString(i18n("Error importing file %1\n%2")).arg(*it).arg(error) );
			else
				m_view->import( *importer );

			if ( importer->getWarningMsgs().count() > 0 )
			{
				warnings_list += QString(i18n("The file \"%1\" generated the following warnings:")).arg(*it);
				warnings_list += importer->getWarningMsgs();
			}

			delete importer;
		}

		if ( warnings_list.count() > 0 )
		{
			warnings_list.prepend(i18n("NOTE: We recommend that all recipes generating warnings be checked to ensure that they were properly imported, and no loss of recipe data has occured."));

			KTextEdit *warningEdit = new KTextEdit( this );
			warningEdit->setText( warnings_list.join("\n\n") );
			warningEdit->setReadOnly(true);

			KDialogBase showWarningsDlg( KDialogBase::Swallow, i18n("Import warnings"), KDialogBase::Ok, KDialogBase::Default, this );
			showWarningsDlg.setMainWidget( warningEdit ); //KDialogBase will delete warningEdit for us
			showWarningsDlg.resize( QSize(550,250) );
			showWarningsDlg.exec();
		}

		//TODO: to just reload the active panel would be preferable
		m_view->selectPanel->reload();
		m_view->ingredientsPanel->reload();
		m_view->propertiesPanel->reload();
		m_view->unitsPanel->reload();
		m_view->shoppingListPanel->reload();
		m_view->categoriesPanel->reload();
		m_view->authorsPanel->reload();
	}
}

void Krecipes::pageSetupSlot()
{
	Recipe recipe;
	m_view->selectPanel->getCurrentRecipe(&recipe);

	PageSetupDialog *page_setup = new PageSetupDialog(this,recipe);
	page_setup->exec();

	delete page_setup;
}

//return true to close app
bool Krecipes::queryClose()
{
	if ( !m_view->inputPanel->everythingSaved() )
	{
		switch( KMessageBox::questionYesNoCancel( this,
		  i18n("A recipe contains unsaved changes.\n"
		  "Do you want to save the changes before exiting?"),
		  i18n("Unsaved Changes") ) )
		{
		case KMessageBox::Yes: m_view->save();
		case KMessageBox::No: return true;
		case KMessageBox::Cancel: return false;
		default: return true;
		}
	}
	else
		return true;
}

void Krecipes::optionsShowToolbar()
{
    // this is all very cut and paste code for showing/hiding the
    // toolbar
    if (m_toolbarAction->isChecked())
        toolBar()->show();
    else
        toolBar()->hide();
}

void Krecipes::optionsShowStatusbar()
{
    // this is all very cut and paste code for showing/hiding the
    // statusbar
    if (m_statusbarAction->isChecked())
        statusBar()->show();
    else
        statusBar()->hide();
}

void Krecipes::optionsConfigureKeys()
{
#if defined(KDE_MAKE_VERSION)
# if KDE_VERSION > KDE_MAKE_VERSION(3,1,4)
   // for KDE 3.2: KKeyDialog::configureKeys is deprecated
   KKeyDialog::configure(actionCollection(), this, true);
 #else
    KKeyDialog::configureKeys(actionCollection(), "krecipesui.rc");
#endif
 #else
  KKeyDialog::configureKeys(actionCollection(), "krecipesui.rc");
#endif
}

void Krecipes::optionsConfigureToolbars()
{
    // use the standard toolbar editor
#if defined(KDE_MAKE_VERSION)
# if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0)
    saveMainWindowSettings(KGlobal::config(), autoSaveGroup());
# else
    saveMainWindowSettings(KGlobal::config());
# endif
#else
    saveMainWindowSettings(KGlobal::config());
#endif
    KEditToolbar dlg(actionCollection());
    connect(&dlg, SIGNAL(newToolbarConfig()), this, SLOT(newToolbarConfig()));
    dlg.exec();
}

void Krecipes::newToolbarConfig()
{
    // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
    // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
    createGUI();

#if defined(KDE_MAKE_VERSION)
# if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0)
    applyMainWindowSettings(KGlobal::config(), autoSaveGroup());
# else
    applyMainWindowSettings(KGlobal::config());
# endif
#else
    applyMainWindowSettings(KGlobal::config());
#endif
}

void Krecipes::optionsPreferences()
{

#if KDE_IS_VERSION(3,1,92 )

     if(KAutoConfigDialog::showDialog("settings"))
		return;

    KAutoConfigDialog *dialog = new KAutoConfigDialog(this, "settings");
    dialog->addPage(new serverprefs(0, "serverprefs"), i18n("Server Settings"), "Server", "identity", i18n("Database Server Options"));
    dialog->addPage(new unitsprefs(0, "NumberFormat"), i18n("Units"), "Units", "frac", i18n("Customize Units"));
    dialog->addPage(new importprefs(0, "Import"), i18n("Units"), "Import", "redo", i18n("Recipe Import Options"));
    //connect(dialog, SIGNAL(settingsChanged()), this, SLOT(loadSettings()));
    dialog->show();
# else
   // popup some sort of preference dialog, here
    KrecipesPreferences dlg(this);
    if (dlg.exec())
    {}
# endif

}

void Krecipes::changeStatusbar(const QString& text)
{
    // display the text on the statusbar
    statusBar()->message(text);
}

void Krecipes::changeCaption(const QString& text)
{
    // display the text on the caption
    setCaption(text);
}
void Krecipes::enableSaveOption(bool en)
{
saveAction->setEnabled(en);
}

#include "krecipes.moc"
<|endoftext|>


<commit_before>#include <string>

#include "Option.h"

#include "Interpreter.h"

#include "FatalErrorCode.h"
#include "ErrorHandler.h"

namespace lyrics
{
	using std::u16string;

	const u16string Tokenizer::BREAK = u"break";
	const u16string Tokenizer::CASE = u"case";
	const u16string Tokenizer::CLASS = u"class";
	const u16string Tokenizer::DEF = u"def";
	const u16string Tokenizer::DO = u"do";
	const u16string Tokenizer::END = u"end";
	const u16string Tokenizer::ELSE = u"else";
	const u16string Tokenizer::ELSEIF = u"elseif";
	const u16string Tokenizer::FALSE = u"false";
	const u16string Tokenizer::FOR = u"for";
	const u16string Tokenizer::FOREACH = u"foreach";
	const u16string Tokenizer::IF = u"if";
	const u16string Tokenizer::IMPORT = u"import";
	const u16string Tokenizer::IN = u"in";
	const u16string Tokenizer::INCLUDE = u"include";
	const u16string Tokenizer::NEXT = u"next";
	const u16string Tokenizer::NULL_TOKEN = u"null";
	const u16string Tokenizer::OUT = u"out";
	const u16string Tokenizer::PACKAGE = u"package";
	const u16string Tokenizer::PRIVATE = u"private";
	const u16string Tokenizer::PROTECTED = u"protected";
	const u16string Tokenizer::PUBLIC = u"public";
	const u16string Tokenizer::RETURN = u"return";
	const u16string Tokenizer::THEN = u"then";
	const u16string Tokenizer::THIS = u"this";
	const u16string Tokenizer::TRUE = u"true";
	const u16string Tokenizer::WHEN = u"when";
	const u16string Tokenizer::WHILE = u"while";

	forward_list<Token>::const_iterator Interpreter::mToken;
	unordered_map<u16string, Literal> Interpreter::mSymbolTable;

	constexpr char ErrorHandler::WARNING[];
	constexpr char ErrorHandler::ERROR[];
	constexpr char ErrorHandler::FATAL_ERROR[];
}

int main( int argc, char *argv[] )
{
	const lyrics::Option option = lyrics::Option( argc, argv );

	if ( option.GetSourceFileName().empty() )
	{
		lyrics::Logger::ErrorHandler( lyrics::FatalErrorCode::NO_INPUT_FILES );
		return 0;
	}

	if ( !lyrics::Interpreter::Interpret( option.GetSourceFileName() ) )
	{
		// TODO:
		return 0;
	}

	return 0;
}
<commit_msg>Use ErrorHandler<commit_after>#include <string>

#include "Option.h"

#include "Interpreter.h"

#include "FatalErrorCode.h"
#include "ErrorHandler.h"

namespace lyrics
{
	using std::u16string;

	const u16string Tokenizer::BREAK = u"break";
	const u16string Tokenizer::CASE = u"case";
	const u16string Tokenizer::CLASS = u"class";
	const u16string Tokenizer::DEF = u"def";
	const u16string Tokenizer::DO = u"do";
	const u16string Tokenizer::END = u"end";
	const u16string Tokenizer::ELSE = u"else";
	const u16string Tokenizer::ELSEIF = u"elseif";
	const u16string Tokenizer::FALSE = u"false";
	const u16string Tokenizer::FOR = u"for";
	const u16string Tokenizer::FOREACH = u"foreach";
	const u16string Tokenizer::IF = u"if";
	const u16string Tokenizer::IMPORT = u"import";
	const u16string Tokenizer::IN = u"in";
	const u16string Tokenizer::INCLUDE = u"include";
	const u16string Tokenizer::NEXT = u"next";
	const u16string Tokenizer::NULL_TOKEN = u"null";
	const u16string Tokenizer::OUT = u"out";
	const u16string Tokenizer::PACKAGE = u"package";
	const u16string Tokenizer::PRIVATE = u"private";
	const u16string Tokenizer::PROTECTED = u"protected";
	const u16string Tokenizer::PUBLIC = u"public";
	const u16string Tokenizer::RETURN = u"return";
	const u16string Tokenizer::THEN = u"then";
	const u16string Tokenizer::THIS = u"this";
	const u16string Tokenizer::TRUE = u"true";
	const u16string Tokenizer::WHEN = u"when";
	const u16string Tokenizer::WHILE = u"while";

	forward_list<Token>::const_iterator Interpreter::mToken;
	unordered_map<u16string, Literal> Interpreter::mSymbolTable;

	constexpr char ErrorHandler::WARNING[];
	constexpr char ErrorHandler::ERROR[];
	constexpr char ErrorHandler::FATAL_ERROR[];
}

int main( int argc, char *argv[] )
{
	const lyrics::Option option = lyrics::Option( argc, argv );

	if ( option.GetSourceFileName().empty() )
	{
		lyrics::ErrorHandler::FatalError( lyrics::FatalErrorCode::NO_INPUT_FILES );
		return 0;
	}

	if ( !lyrics::Interpreter::Interpret( option.GetSourceFileName() ) )
	{
		// TODO:
		return 0;
	}

	return 0;
}
<|endoftext|>


<commit_before>//===-- DWARFASTParserSwift.cpp ---------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 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 "DWARFASTParserSwift.h"

#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
#include "DWARFDIE.h"
#include "DWARFDebugInfo.h"
#include "DWARFDefines.h"
#include "SymbolFileDWARF.h"

#include "swift/AST/ASTContext.h"
#include "swift/Demangling/Demangle.h"

#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SwiftASTContext.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/SwiftLanguageRuntime.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"

using namespace lldb;
using namespace lldb_private;

DWARFASTParserSwift::DWARFASTParserSwift(SwiftASTContext &ast) : m_ast(ast) {}

DWARFASTParserSwift::~DWARFASTParserSwift() {}

static llvm::StringRef GetTypedefName(const DWARFDIE &die) {
  if (die.Tag() != DW_TAG_typedef)
    return {};
  DWARFDIE type_die = die.GetAttributeValueAsReferenceDIE(DW_AT_type);
  if (!type_die.IsValid())
    return {};
  return llvm::StringRef::withNullAsEmpty(type_die.GetName());
}

lldb::TypeSP DWARFASTParserSwift::ParseTypeFromDWARF(const SymbolContext &sc,
                                                     const DWARFDIE &die,
                                                     Log *log,
                                                     bool *type_is_new_ptr) {
  lldb::TypeSP type_sp;
  CompilerType compiler_type;
  Status error;

  Declaration decl;
  ConstString mangled_name;
  ConstString name;
  bool is_clang_type = false;
  llvm::Optional<uint64_t> dwarf_byte_size;

  DWARFAttributes attributes;
  const size_t num_attributes = die.GetAttributes(attributes);
  DWARFFormValue type_attr;

  if (num_attributes > 0) {
    uint32_t i;
    for (i = 0; i < num_attributes; ++i) {
      const dw_attr_t attr = attributes.AttributeAtIndex(i);
      DWARFFormValue form_value;
      if (attributes.ExtractFormValueAtIndex(i, form_value)) {
        switch (attr) {
        case DW_AT_decl_file:
          decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
              form_value.Unsigned()));
          break;
        case DW_AT_decl_line:
          decl.SetLine(form_value.Unsigned());
          break;
        case DW_AT_decl_column:
          decl.SetColumn(form_value.Unsigned());
          break;
        case DW_AT_name:
          name.SetCString(form_value.AsCString());
          break;
        case DW_AT_linkage_name:
        case DW_AT_MIPS_linkage_name:
          mangled_name.SetCString(form_value.AsCString());
          break;
        case DW_AT_byte_size:
          dwarf_byte_size = form_value.Unsigned();
          break;
        default:
          break;
        }
      }
    }
  }

  if (!mangled_name && name) {
    if (name.GetStringRef().equals("$swift.fixedbuffer")) {
      DWARFDIE type_die =
          die.GetFirstChild().GetAttributeValueAsReferenceDIE(DW_AT_type);
      if (auto wrapped_type =
          ParseTypeFromDWARF(sc, type_die, log, type_is_new_ptr)) {
        // Create a unique pointer for the type + fixed buffer flag.
        type_sp.reset(new Type(*wrapped_type));
        type_sp->SetSwiftFixedValueBuffer(true);
        return type_sp;
      }
    }
    if (SwiftLanguageRuntime::IsSwiftMangledName(name.GetCString()))
      mangled_name = name;
    else {
      const char *type_name_cstr = name.GetCString();
      // TODO: remove this once all mangled names are always included for all
      // types in DWARF
      swift::ModuleDecl *swift_module = m_ast.GetModule(decl.GetFile(), error);
      if (swift_module)
        compiler_type = m_ast.FindType(type_name_cstr, swift_module);
    }
  }

  if (mangled_name) {
    type_sp = m_ast.GetCachedType(mangled_name);
    if (type_sp)
      return type_sp;

    // Try to import the type from one of the loaded Swift modules.
    compiler_type =
        m_ast.GetTypeFromMangledTypename(mangled_name.GetCString(), error);
  }

  if (!compiler_type &&
      swift::Demangle::isObjCSymbol(mangled_name.GetStringRef())) {
    // When we failed to look up the type because no .swiftmodule is
    // present or it couldn't be read, fall back to presenting objects
    // that look like they might be come from Objective-C (or C) as
    // Clang types. LLDB's Objective-C part is very robust against
    // malformed object pointers, so this isn't very risky.
    if (auto *clang_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
            sc.module_sp->GetTypeSystemForLanguage(eLanguageTypeObjC))) {
      DWARFASTParserClang *clang_ast_parser =
          static_cast<DWARFASTParserClang *>(clang_ctx->GetDWARFParser());
      TypeMap clang_types;
      GetClangType(die, mangled_name.GetStringRef(), clang_types);

      // Import the Clang type into the Clang context.
      if (clang_types.GetSize())
        if (TypeSP clang_type_sp = clang_types.GetTypeAtIndex(0))
          if (clang_type_sp) {
            is_clang_type = true;
            compiler_type = clang_ast_parser->GetClangASTImporter().CopyType(
                *clang_ctx, clang_type_sp->GetForwardCompilerType());
            // Swift doesn't know pointers. Convert top-level
            // Objective-C object types to object pointers for Clang.
            auto clang_type = clang::QualType::getFromOpaquePtr(
                compiler_type.GetOpaqueQualType());
            if (clang_type->isObjCObjectOrInterfaceType())
              compiler_type = compiler_type.GetPointerType();
          }

      // Fall back to (id), which is not necessarily correct.
      if (!compiler_type) {
        is_clang_type = true;
        compiler_type = clang_ctx->GetBasicType(eBasicTypeObjCClass);
      }
    }
  }

  ConstString preferred_name;
  if (!compiler_type && name) {
    // Handle Archetypes, which are typedefs to RawPointerType.
    if (GetTypedefName(die).startswith("$sBp")) {
      swift::ASTContext *swift_ast_ctx = m_ast.GetASTContext();
      if (!swift_ast_ctx) {
        if (log)
          log->Printf("Empty Swift AST context while looking up %s.",
                      name.AsCString());
        return {};
      }
      preferred_name = name;
      compiler_type = {swift_ast_ctx->TheRawPointerType};
    }
  }

  switch (die.Tag()) {
  case DW_TAG_inlined_subroutine:
  case DW_TAG_subprogram:
  case DW_TAG_subroutine_type:
    if (!compiler_type || !compiler_type.IsFunctionType()) {
      // Make sure we at least have some function type. The mangling for
      // the "top_level_code" is returning the empty tuple type "()",
      // which is not a function type.
      compiler_type = m_ast.GetVoidFunctionType();
    }
    break;
  default:
    break;
  }

  if (compiler_type) {
    type_sp = TypeSP(new Type(
        die.GetID(), die.GetDWARF(),
        preferred_name ? preferred_name : compiler_type.GetTypeName(),
        is_clang_type ? dwarf_byte_size
                      : compiler_type.GetByteSize(nullptr),
        NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
        is_clang_type ? Type::eResolveStateForward : Type::eResolveStateFull));
    // FIXME: This ought to work lazily, too.
    if (is_clang_type)
      type_sp->GetFullCompilerType();
  }

  // Cache this type.
  if (type_sp && mangled_name &&
      SwiftLanguageRuntime::IsSwiftMangledName(mangled_name.GetCString()))
    m_ast.SetCachedType(mangled_name, type_sp);

  return type_sp;
}

void DWARFASTParserSwift::GetClangType(const DWARFDIE &die,
                                       llvm::StringRef mangled_name,
                                       TypeMap &clang_types) const {
  std::vector<CompilerContext> decl_context;
  die.GetDeclContext(decl_context);
  if (!decl_context.size())
    return;

  // Typedefs don't have a DW_AT_linkage_name, so their DW_AT_name is the
  // mangled. Get the unmangled name.
  auto fixup_typedef = [&mangled_name, &decl_context]() {
    using namespace swift::Demangle;
    Context Ctx;
    NodePointer node = Ctx.demangleSymbolAsNode(mangled_name);
    if (!node || node->getNumChildren() != 1 ||
        node->getKind() != Node::Kind::Global)
      return;
    node = node->getFirstChild();
    if (node->getNumChildren() != 1 ||
        node->getKind() != Node::Kind::TypeMangling)
      return;
    node = node->getFirstChild();
    if (node->getNumChildren() != 1 || node->getKind() != Node::Kind::Type)
      return;
    node = node->getFirstChild();
    if (node->getKind() != Node::Kind::TypeAlias)
      return;
    for (NodePointer child : *node)
      if (child->getKind() == Node::Kind::Identifier && child->hasText()) {
        decl_context.back().type = CompilerContextKind::Typedef;
        decl_context.back().name = ConstString(child->getText());
        return;
      }
  };
  fixup_typedef();

  auto *sym_file = die.GetCU()->GetSymbolFileDWARF();
  sym_file->UpdateExternalModuleListIfNeeded();

  CompilerContextKind kinds[] = {decl_context.back().type,
                                 CompilerContextKind::Union,
                                 CompilerContextKind::Enumeration};

  // The Swift projection of all Clang type is a struct; search every kind.
  for (CompilerContextKind kind : kinds) {
    decl_context.back().type = kind;
    // Search any modules referenced by DWARF.
    for (const auto &name_module : sym_file->getExternalTypeModules()) {
      if (!name_module.second)
        continue;
      SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor();
      if (sym_vendor->FindTypes(decl_context, true, clang_types))
        return;
    }
    // Next search the .dSYM the DIE came from, if applicable.
    if (SymbolFileDWARF *sym_file = die.GetCU()->GetSymbolFileDWARF())
      if (sym_file->FindTypes(decl_context, true, clang_types))
        return;
  }
}

Function *DWARFASTParserSwift::ParseFunctionFromDWARF(
    lldb_private::CompileUnit &comp_unit, const DWARFDIE &die) {
  DWARFRangeList func_ranges;
  const char *name = NULL;
  const char *mangled = NULL;
  int decl_file = 0;
  int decl_line = 0;
  int decl_column = 0;
  int call_file = 0;
  int call_line = 0;
  int call_column = 0;
  DWARFExpression frame_base(die.GetCU());

  if (die.Tag() != DW_TAG_subprogram)
    return NULL;

  if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
                               decl_column, call_file, call_line, call_column,
                               &frame_base)) {
    // Union of all ranges in the function DIE (if the function is
    // discontiguous)
    SymbolFileDWARF *dwarf = die.GetDWARF();
    AddressRange func_range;
    lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
    lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
    if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
        lowest_func_addr <= highest_func_addr) {
      ModuleSP module_sp(dwarf->GetObjectFile()->GetModule());
      func_range.GetBaseAddress().ResolveAddressUsingFileSections(
          lowest_func_addr, module_sp->GetSectionList());
      if (func_range.GetBaseAddress().IsValid())
        func_range.SetByteSize(highest_func_addr - lowest_func_addr);
    }

    if (func_range.GetBaseAddress().IsValid()) {
      Mangled func_name;
      if (mangled)
        func_name.SetValue(ConstString(mangled), true);
      else
        func_name.SetValue(ConstString(name), false);

      // See if this function can throw.  We can't get that from the
      // mangled name (even though the information is often there)
      // because Swift reserves the right to omit it from the name
      // if it doesn't need it.  So instead we look for the
      // DW_TAG_thrown_type:

      bool can_throw = false;

      DWARFDebugInfoEntry *child(die.GetFirstChild().GetDIE());
      while (child) {
        if (child->Tag() == DW_TAG_thrown_type) {
          can_throw = true;
          break;
        }
        child = child->GetSibling();
      }

      FunctionSP func_sp;
      std::unique_ptr<Declaration> decl_ap;
      if (decl_file != 0 || decl_line != 0 || decl_column != 0)
        decl_ap.reset(new Declaration(
            comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
            decl_line, decl_column));

      if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
        const user_id_t func_user_id = die.GetID();
        func_sp.reset(new Function(&comp_unit, func_user_id, func_user_id,
                                   func_name, nullptr, func_range,
                                   can_throw)); // first address range

        if (func_sp.get() != NULL) {
          if (frame_base.IsValid())
            func_sp->GetFrameBaseExpression() = frame_base;
          comp_unit.AddFunction(func_sp);
          return func_sp.get();
        }
      }
    }
  }
  return NULL;
}

lldb_private::CompilerDeclContext
DWARFASTParserSwift::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
  return CompilerDeclContext();
}

lldb_private::CompilerDeclContext
DWARFASTParserSwift::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
  return CompilerDeclContext();
}
<commit_msg>[DWARF] Fix Swift build after r361849<commit_after>//===-- DWARFASTParserSwift.cpp ---------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 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 "DWARFASTParserSwift.h"

#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
#include "DWARFDIE.h"
#include "DWARFDebugInfo.h"
#include "DWARFDefines.h"
#include "SymbolFileDWARF.h"

#include "swift/AST/ASTContext.h"
#include "swift/Demangling/Demangle.h"

#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SwiftASTContext.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/SwiftLanguageRuntime.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"

using namespace lldb;
using namespace lldb_private;

DWARFASTParserSwift::DWARFASTParserSwift(SwiftASTContext &ast) : m_ast(ast) {}

DWARFASTParserSwift::~DWARFASTParserSwift() {}

static llvm::StringRef GetTypedefName(const DWARFDIE &die) {
  if (die.Tag() != DW_TAG_typedef)
    return {};
  DWARFDIE type_die = die.GetAttributeValueAsReferenceDIE(DW_AT_type);
  if (!type_die.IsValid())
    return {};
  return llvm::StringRef::withNullAsEmpty(type_die.GetName());
}

lldb::TypeSP DWARFASTParserSwift::ParseTypeFromDWARF(const SymbolContext &sc,
                                                     const DWARFDIE &die,
                                                     Log *log,
                                                     bool *type_is_new_ptr) {
  lldb::TypeSP type_sp;
  CompilerType compiler_type;
  Status error;

  Declaration decl;
  ConstString mangled_name;
  ConstString name;
  bool is_clang_type = false;
  llvm::Optional<uint64_t> dwarf_byte_size;

  DWARFAttributes attributes;
  const size_t num_attributes = die.GetAttributes(attributes);
  DWARFFormValue type_attr;

  if (num_attributes > 0) {
    uint32_t i;
    for (i = 0; i < num_attributes; ++i) {
      const dw_attr_t attr = attributes.AttributeAtIndex(i);
      DWARFFormValue form_value;
      if (attributes.ExtractFormValueAtIndex(i, form_value)) {
        switch (attr) {
        case DW_AT_decl_file:
          decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
              form_value.Unsigned()));
          break;
        case DW_AT_decl_line:
          decl.SetLine(form_value.Unsigned());
          break;
        case DW_AT_decl_column:
          decl.SetColumn(form_value.Unsigned());
          break;
        case DW_AT_name:
          name.SetCString(form_value.AsCString());
          break;
        case DW_AT_linkage_name:
        case DW_AT_MIPS_linkage_name:
          mangled_name.SetCString(form_value.AsCString());
          break;
        case DW_AT_byte_size:
          dwarf_byte_size = form_value.Unsigned();
          break;
        default:
          break;
        }
      }
    }
  }

  if (!mangled_name && name) {
    if (name.GetStringRef().equals("$swift.fixedbuffer")) {
      DWARFDIE type_die =
          die.GetFirstChild().GetAttributeValueAsReferenceDIE(DW_AT_type);
      if (auto wrapped_type =
          ParseTypeFromDWARF(sc, type_die, log, type_is_new_ptr)) {
        // Create a unique pointer for the type + fixed buffer flag.
        type_sp.reset(new Type(*wrapped_type));
        type_sp->SetSwiftFixedValueBuffer(true);
        return type_sp;
      }
    }
    if (SwiftLanguageRuntime::IsSwiftMangledName(name.GetCString()))
      mangled_name = name;
    else {
      const char *type_name_cstr = name.GetCString();
      // TODO: remove this once all mangled names are always included for all
      // types in DWARF
      swift::ModuleDecl *swift_module = m_ast.GetModule(decl.GetFile(), error);
      if (swift_module)
        compiler_type = m_ast.FindType(type_name_cstr, swift_module);
    }
  }

  if (mangled_name) {
    type_sp = m_ast.GetCachedType(mangled_name);
    if (type_sp)
      return type_sp;

    // Try to import the type from one of the loaded Swift modules.
    compiler_type =
        m_ast.GetTypeFromMangledTypename(mangled_name.GetCString(), error);
  }

  if (!compiler_type &&
      swift::Demangle::isObjCSymbol(mangled_name.GetStringRef())) {
    // When we failed to look up the type because no .swiftmodule is
    // present or it couldn't be read, fall back to presenting objects
    // that look like they might be come from Objective-C (or C) as
    // Clang types. LLDB's Objective-C part is very robust against
    // malformed object pointers, so this isn't very risky.
    if (auto *clang_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
            sc.module_sp->GetTypeSystemForLanguage(eLanguageTypeObjC))) {
      DWARFASTParserClang *clang_ast_parser =
          static_cast<DWARFASTParserClang *>(clang_ctx->GetDWARFParser());
      TypeMap clang_types;
      GetClangType(die, mangled_name.GetStringRef(), clang_types);

      // Import the Clang type into the Clang context.
      if (clang_types.GetSize())
        if (TypeSP clang_type_sp = clang_types.GetTypeAtIndex(0))
          if (clang_type_sp) {
            is_clang_type = true;
            compiler_type = clang_ast_parser->GetClangASTImporter().CopyType(
                *clang_ctx, clang_type_sp->GetForwardCompilerType());
            // Swift doesn't know pointers. Convert top-level
            // Objective-C object types to object pointers for Clang.
            auto clang_type = clang::QualType::getFromOpaquePtr(
                compiler_type.GetOpaqueQualType());
            if (clang_type->isObjCObjectOrInterfaceType())
              compiler_type = compiler_type.GetPointerType();
          }

      // Fall back to (id), which is not necessarily correct.
      if (!compiler_type) {
        is_clang_type = true;
        compiler_type = clang_ctx->GetBasicType(eBasicTypeObjCClass);
      }
    }
  }

  ConstString preferred_name;
  if (!compiler_type && name) {
    // Handle Archetypes, which are typedefs to RawPointerType.
    if (GetTypedefName(die).startswith("$sBp")) {
      swift::ASTContext *swift_ast_ctx = m_ast.GetASTContext();
      if (!swift_ast_ctx) {
        if (log)
          log->Printf("Empty Swift AST context while looking up %s.",
                      name.AsCString());
        return {};
      }
      preferred_name = name;
      compiler_type = {swift_ast_ctx->TheRawPointerType};
    }
  }

  switch (die.Tag()) {
  case DW_TAG_inlined_subroutine:
  case DW_TAG_subprogram:
  case DW_TAG_subroutine_type:
    if (!compiler_type || !compiler_type.IsFunctionType()) {
      // Make sure we at least have some function type. The mangling for
      // the "top_level_code" is returning the empty tuple type "()",
      // which is not a function type.
      compiler_type = m_ast.GetVoidFunctionType();
    }
    break;
  default:
    break;
  }

  if (compiler_type) {
    type_sp = TypeSP(new Type(
        die.GetID(), die.GetDWARF(),
        preferred_name ? preferred_name : compiler_type.GetTypeName(),
        is_clang_type ? dwarf_byte_size
                      : compiler_type.GetByteSize(nullptr),
        NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
        is_clang_type ? Type::eResolveStateForward : Type::eResolveStateFull));
    // FIXME: This ought to work lazily, too.
    if (is_clang_type)
      type_sp->GetFullCompilerType();
  }

  // Cache this type.
  if (type_sp && mangled_name &&
      SwiftLanguageRuntime::IsSwiftMangledName(mangled_name.GetCString()))
    m_ast.SetCachedType(mangled_name, type_sp);

  return type_sp;
}

void DWARFASTParserSwift::GetClangType(const DWARFDIE &die,
                                       llvm::StringRef mangled_name,
                                       TypeMap &clang_types) const {
  std::vector<CompilerContext> decl_context;
  die.GetDeclContext(decl_context);
  if (!decl_context.size())
    return;

  // Typedefs don't have a DW_AT_linkage_name, so their DW_AT_name is the
  // mangled. Get the unmangled name.
  auto fixup_typedef = [&mangled_name, &decl_context]() {
    using namespace swift::Demangle;
    Context Ctx;
    NodePointer node = Ctx.demangleSymbolAsNode(mangled_name);
    if (!node || node->getNumChildren() != 1 ||
        node->getKind() != Node::Kind::Global)
      return;
    node = node->getFirstChild();
    if (node->getNumChildren() != 1 ||
        node->getKind() != Node::Kind::TypeMangling)
      return;
    node = node->getFirstChild();
    if (node->getNumChildren() != 1 || node->getKind() != Node::Kind::Type)
      return;
    node = node->getFirstChild();
    if (node->getKind() != Node::Kind::TypeAlias)
      return;
    for (NodePointer child : *node)
      if (child->getKind() == Node::Kind::Identifier && child->hasText()) {
        decl_context.back().type = CompilerContextKind::Typedef;
        decl_context.back().name = ConstString(child->getText());
        return;
      }
  };
  fixup_typedef();

  auto *sym_file = die.GetCU()->GetSymbolFileDWARF();
  sym_file->UpdateExternalModuleListIfNeeded();

  CompilerContextKind kinds[] = {decl_context.back().type,
                                 CompilerContextKind::Union,
                                 CompilerContextKind::Enumeration};

  // The Swift projection of all Clang type is a struct; search every kind.
  for (CompilerContextKind kind : kinds) {
    decl_context.back().type = kind;
    // Search any modules referenced by DWARF.
    for (const auto &name_module : sym_file->getExternalTypeModules()) {
      if (!name_module.second)
        continue;
      SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor();
      if (sym_vendor->FindTypes(decl_context, true, clang_types))
        return;
    }
    // Next search the .dSYM the DIE came from, if applicable.
    if (SymbolFileDWARF *sym_file = die.GetCU()->GetSymbolFileDWARF())
      if (sym_file->FindTypes(decl_context, true, clang_types))
        return;
  }
}

Function *DWARFASTParserSwift::ParseFunctionFromDWARF(
    lldb_private::CompileUnit &comp_unit, const DWARFDIE &die) {
  DWARFRangeList func_ranges;
  const char *name = NULL;
  const char *mangled = NULL;
  int decl_file = 0;
  int decl_line = 0;
  int decl_column = 0;
  int call_file = 0;
  int call_line = 0;
  int call_column = 0;
  DWARFExpression frame_base;

  if (die.Tag() != DW_TAG_subprogram)
    return NULL;

  if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
                               decl_column, call_file, call_line, call_column,
                               &frame_base)) {
    // Union of all ranges in the function DIE (if the function is
    // discontiguous)
    SymbolFileDWARF *dwarf = die.GetDWARF();
    AddressRange func_range;
    lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
    lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
    if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
        lowest_func_addr <= highest_func_addr) {
      ModuleSP module_sp(dwarf->GetObjectFile()->GetModule());
      func_range.GetBaseAddress().ResolveAddressUsingFileSections(
          lowest_func_addr, module_sp->GetSectionList());
      if (func_range.GetBaseAddress().IsValid())
        func_range.SetByteSize(highest_func_addr - lowest_func_addr);
    }

    if (func_range.GetBaseAddress().IsValid()) {
      Mangled func_name;
      if (mangled)
        func_name.SetValue(ConstString(mangled), true);
      else
        func_name.SetValue(ConstString(name), false);

      // See if this function can throw.  We can't get that from the
      // mangled name (even though the information is often there)
      // because Swift reserves the right to omit it from the name
      // if it doesn't need it.  So instead we look for the
      // DW_TAG_thrown_type:

      bool can_throw = false;

      DWARFDebugInfoEntry *child(die.GetFirstChild().GetDIE());
      while (child) {
        if (child->Tag() == DW_TAG_thrown_type) {
          can_throw = true;
          break;
        }
        child = child->GetSibling();
      }

      FunctionSP func_sp;
      std::unique_ptr<Declaration> decl_ap;
      if (decl_file != 0 || decl_line != 0 || decl_column != 0)
        decl_ap.reset(new Declaration(
            comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
            decl_line, decl_column));

      if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
        const user_id_t func_user_id = die.GetID();
        func_sp.reset(new Function(&comp_unit, func_user_id, func_user_id,
                                   func_name, nullptr, func_range,
                                   can_throw)); // first address range

        if (func_sp.get() != NULL) {
          if (frame_base.IsValid())
            func_sp->GetFrameBaseExpression() = frame_base;
          comp_unit.AddFunction(func_sp);
          return func_sp.get();
        }
      }
    }
  }
  return NULL;
}

lldb_private::CompilerDeclContext
DWARFASTParserSwift::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
  return CompilerDeclContext();
}

lldb_private::CompilerDeclContext
DWARFASTParserSwift::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
  return CompilerDeclContext();
}
<|endoftext|>


<commit_before>
#pragma once

#include <sstream>

#include <cppassist/string/manipulation.h>
#include <cppassist/memory/make_unique.inl>

namespace cppexpose
{

template <typename T, typename BASE>
class DirectValue;

template <typename T, typename BASE>
class StoredValue;

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE>::TypedArray()
{
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE>::TypedArray(const TypedArray & rhs)
: Typed<T, BASE>(rhs)
{
    // don't copy m_subValues which will be lazy-initialized when used
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE>::TypedArray(TypedArray && rhs)
: Typed<T, BASE>(std::move(rhs))
, m_subValues(std::move(rhs.m_subValues))
{
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE>::~TypedArray()
{
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE> & TypedArray<T, ET, Size, BASE>::operator=(const TypedArray & rhs)
{
    Typed<T, BASE>::operator=(std::move(rhs));

    // don't copy m_subValues which will be lazy-initialized when used

    return *this;
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE> & TypedArray<T, ET, Size, BASE>::operator=(TypedArray && rhs)
{
    Typed<T, BASE>::operator=(std::move(rhs));

    m_subValues = std::move(rhs.m_subValues);

    return *this;
}

template <typename T, typename ET, size_t Size, typename BASE>
size_t TypedArray<T, ET, Size, BASE>::numElements() const
{
    return Size;
}

template <typename T, typename ET, size_t Size, typename BASE>
std::string TypedArray<T, ET, Size, BASE>::typeName() const
{
    // [TODO] This is not nice and potentially expensive.
    //        Find a better way to get type names.
    DirectValue<ET> dummy;

    std::stringstream s;
    s << "array<" << dummy.typeName() << ", " << Size << ">";
    return s.str();
}

template <typename T, typename ET, size_t Size, typename BASE>
bool TypedArray<T, ET, Size, BASE>::isComposite() const
{
    return true;
}

template <typename T, typename ET, size_t Size, typename BASE>
size_t TypedArray<T, ET, Size, BASE>::numSubValues() const
{
    return Size;
}

template <typename T, typename ET, size_t Size, typename BASE>
AbstractTyped * TypedArray<T, ET, Size, BASE>::subValue(size_t index)
{
    // Create typed accessor for sub-values on first call to this function
    if (m_subValues.empty())
    {
        for (size_t i=0; i<Size; i++)
        {
            m_subValues.push_back(cppassist::make_unique<StoredValue<ET>>(
                [this, i] () -> ET {
                    return this->getElement(i);
                },
                [this, i] (const ET & value) {
                    this->setElement(i, value);
                }
            ));
        }
    }

    // Return sub-value accessor
    return (index < Size) ? m_subValues[index].get() : nullptr;
}

template <typename T, typename ET, size_t Size, typename BASE>
bool TypedArray<T, ET, Size, BASE>::isArray() const
{
    return true;
}

template <typename T, typename ET, size_t Size, typename BASE>
std::string TypedArray<T, ET, Size, BASE>::toString() const
{
    std::string str = "(";

    for (size_t i=0; i<Size; i++) {
        if (i > 0) str += ", ";
        str += const_cast<TypedArray<T, ET, Size, BASE> *>(this)->subValue(i)->toString();
    }

    str += ")";

    return str;
}

template <typename T, typename ET, size_t Size, typename BASE>
bool TypedArray<T, ET, Size, BASE>::fromString(const std::string & value)
{
    std::vector<std::string> elementStrings = cppassist::string::parseArray(value, Size);
    if (elementStrings.size() != Size) {
        return false;
    }

    for (size_t i=0; i<Size; i++)
    {
        if (!this->subValue(i)->fromString(elementStrings[i])) {
            return false;
        }
    }

    return true;
}

} // namespace cppexpose
<commit_msg>Fix std::move in copy assignment<commit_after>
#pragma once

#include <sstream>

#include <cppassist/string/manipulation.h>
#include <cppassist/memory/make_unique.inl>

namespace cppexpose
{

template <typename T, typename BASE>
class DirectValue;

template <typename T, typename BASE>
class StoredValue;

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE>::TypedArray()
{
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE>::TypedArray(const TypedArray & rhs)
: Typed<T, BASE>(rhs)
{
    // don't copy m_subValues which will be lazy-initialized when used
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE>::TypedArray(TypedArray && rhs)
: Typed<T, BASE>(std::move(rhs))
, m_subValues(std::move(rhs.m_subValues))
{
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE>::~TypedArray()
{
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE> & TypedArray<T, ET, Size, BASE>::operator=(const TypedArray & rhs)
{
    Typed<T, BASE>::operator=(rhs);

    // don't copy m_subValues which will be lazy-initialized when used

    return *this;
}

template <typename T, typename ET, size_t Size, typename BASE>
TypedArray<T, ET, Size, BASE> & TypedArray<T, ET, Size, BASE>::operator=(TypedArray && rhs)
{
    Typed<T, BASE>::operator=(std::move(rhs));

    m_subValues = std::move(rhs.m_subValues);

    return *this;
}

template <typename T, typename ET, size_t Size, typename BASE>
size_t TypedArray<T, ET, Size, BASE>::numElements() const
{
    return Size;
}

template <typename T, typename ET, size_t Size, typename BASE>
std::string TypedArray<T, ET, Size, BASE>::typeName() const
{
    // [TODO] This is not nice and potentially expensive.
    //        Find a better way to get type names.
    DirectValue<ET> dummy;

    std::stringstream s;
    s << "array<" << dummy.typeName() << ", " << Size << ">";
    return s.str();
}

template <typename T, typename ET, size_t Size, typename BASE>
bool TypedArray<T, ET, Size, BASE>::isComposite() const
{
    return true;
}

template <typename T, typename ET, size_t Size, typename BASE>
size_t TypedArray<T, ET, Size, BASE>::numSubValues() const
{
    return Size;
}

template <typename T, typename ET, size_t Size, typename BASE>
AbstractTyped * TypedArray<T, ET, Size, BASE>::subValue(size_t index)
{
    // Create typed accessor for sub-values on first call to this function
    if (m_subValues.empty())
    {
        for (size_t i=0; i<Size; i++)
        {
            m_subValues.push_back(cppassist::make_unique<StoredValue<ET>>(
                [this, i] () -> ET {
                    return this->getElement(i);
                },
                [this, i] (const ET & value) {
                    this->setElement(i, value);
                }
            ));
        }
    }

    // Return sub-value accessor
    return (index < Size) ? m_subValues[index].get() : nullptr;
}

template <typename T, typename ET, size_t Size, typename BASE>
bool TypedArray<T, ET, Size, BASE>::isArray() const
{
    return true;
}

template <typename T, typename ET, size_t Size, typename BASE>
std::string TypedArray<T, ET, Size, BASE>::toString() const
{
    std::string str = "(";

    for (size_t i=0; i<Size; i++) {
        if (i > 0) str += ", ";
        str += const_cast<TypedArray<T, ET, Size, BASE> *>(this)->subValue(i)->toString();
    }

    str += ")";

    return str;
}

template <typename T, typename ET, size_t Size, typename BASE>
bool TypedArray<T, ET, Size, BASE>::fromString(const std::string & value)
{
    std::vector<std::string> elementStrings = cppassist::string::parseArray(value, Size);
    if (elementStrings.size() != Size) {
        return false;
    }

    for (size_t i=0; i<Size; i++)
    {
        if (!this->subValue(i)->fromString(elementStrings[i])) {
            return false;
        }
    }

    return true;
}

} // namespace cppexpose
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "WorldWeapons.h"
#include "ShotUpdate.h"
#include "Protocol.h"
#include "Address.h"

char *getDirectMessageBuffer();
void broadcastMessage(uint16_t code, int len, const void *msg);

WorldWeapons::WorldWeapons()
: worldShotId(0)
{
}

WorldWeapons::~WorldWeapons()
{
  for (std::vector<Weapon*>::iterator it = weapons.begin(); it != weapons.end(); ++it) {
    Weapon *w = *it;
    delete w;
  }
  weapons.clear();
}

void WorldWeapons::fire()
{
  for (std::vector<Weapon*>::iterator it = weapons.begin(); it != weapons.end(); ++it) {
    Weapon *w = *it;
    if (w->nextTime <= TimeKeeper::getCurrent()) {

      void *buf, *bufStart = getDirectMessageBuffer();

      FiringInfo firingInfo;
      firingInfo.flagType = (FlagType*)w->type;
      firingInfo.lifetime = BZDB->eval(StateDatabase::BZDB_RELOADTIME);
      firingInfo.shot.player = ServerPlayer;
      memmove(firingInfo.shot.pos, w->origin, 3 * sizeof(float));
      float shotSpeed = BZDB->eval(StateDatabase::BZDB_SHOTSPEED);
      firingInfo.shot.vel[0] = shotSpeed*cos(w->direction);
      firingInfo.shot.vel[1] = shotSpeed*sin(w->direction);
      firingInfo.shot.vel[2] = 0.0f;
      firingInfo.shot.id = worldShotId++;
      if (worldShotId > 30) // Maximum of 30 world shots
        worldShotId = 0;
      firingInfo.shot.dt = 0;
      buf = firingInfo.pack(bufStart);

      broadcastMessage(MsgShotBegin, (char *)buf - (char *)bufStart, bufStart);

      //Set up timer for next shot
      w->nextTime += w->delay[w->nextDelay];
      w->nextDelay++;
      if (w->nextDelay == (int)w->delay.size())
        w->nextDelay = 0;
    }
  }
}

void WorldWeapons::add(const FlagType *type, const float *origin, float direction, float initdelay, const std::vector<float> &delay, TimeKeeper &sync)
{
  Weapon *w = new Weapon();
  w->type = type;
  memmove(&w->origin, origin, 3*sizeof(float));
  w->direction = direction;
  w->nextTime = sync;
  w->nextTime += initdelay;
  w->nextDelay = 0;
  w->delay = delay;

  weapons.push_back(w);
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>header comment foo<commit_after>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// class-interface header
#include "WorldWeapons.h"

// common-interface headers
#include "ShotUpdate.h"
#include "Protocol.h"
#include "Address.h"

char *getDirectMessageBuffer();
void broadcastMessage(uint16_t code, int len, const void *msg);

WorldWeapons::WorldWeapons()
: worldShotId(0)
{
}

WorldWeapons::~WorldWeapons()
{
  for (std::vector<Weapon*>::iterator it = weapons.begin(); it != weapons.end(); ++it) {
    Weapon *w = *it;
    delete w;
  }
  weapons.clear();
}

void WorldWeapons::fire()
{
  for (std::vector<Weapon*>::iterator it = weapons.begin(); it != weapons.end(); ++it) {
    Weapon *w = *it;
    if (w->nextTime <= TimeKeeper::getCurrent()) {

      void *buf, *bufStart = getDirectMessageBuffer();

      FiringInfo firingInfo;
      firingInfo.flagType = (FlagType*)w->type;
      firingInfo.lifetime = BZDB->eval(StateDatabase::BZDB_RELOADTIME);
      firingInfo.shot.player = ServerPlayer;
      memmove(firingInfo.shot.pos, w->origin, 3 * sizeof(float));
      float shotSpeed = BZDB->eval(StateDatabase::BZDB_SHOTSPEED);
      firingInfo.shot.vel[0] = shotSpeed*cos(w->direction);
      firingInfo.shot.vel[1] = shotSpeed*sin(w->direction);
      firingInfo.shot.vel[2] = 0.0f;
      firingInfo.shot.id = worldShotId++;
      if (worldShotId > 30) // Maximum of 30 world shots
        worldShotId = 0;
      firingInfo.shot.dt = 0;
      buf = firingInfo.pack(bufStart);

      broadcastMessage(MsgShotBegin, (char *)buf - (char *)bufStart, bufStart);

      //Set up timer for next shot
      w->nextTime += w->delay[w->nextDelay];
      w->nextDelay++;
      if (w->nextDelay == (int)w->delay.size())
        w->nextDelay = 0;
    }
  }
}

void WorldWeapons::add(const FlagType *type, const float *origin, float direction, float initdelay, const std::vector<float> &delay, TimeKeeper &sync)
{
  Weapon *w = new Weapon();
  w->type = type;
  memmove(&w->origin, origin, 3*sizeof(float));
  w->direction = direction;
  w->nextTime = sync;
  w->nextTime += initdelay;
  w->nextDelay = 0;
  w->delay = delay;

  weapons.push_back(w);
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2013 The Communi Project
 *
 * This example is free, and not covered by the LGPL license. There is no
 * restriction applied to their modification, redistribution, using and so on.
 * You can study them, modify them, use them in your own program - either
 * completely or partially.
 */

#include "bufferview.h"
#include "textdocument.h"
#include "textbrowser.h"
#include "textinput.h"
#include "listview.h"
#include "titlebar.h"
#include <IrcBufferModel>
#include <QApplication>
#include <QVBoxLayout>
#include <IrcChannel>
#include <IrcBuffer>

BufferView::BufferView(QWidget* parent) : QWidget(parent)
{
    d.titleBar = new TitleBar(this);
    d.listView = new ListView(this);
    d.textInput = new TextInput(this);
    d.textBrowser = new TextBrowser(this);
    d.textBrowser->setBuddy(d.textInput);

    d.splitter = new QSplitter(this);
    d.splitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);

    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->setSpacing(0);
    layout->setMargin(0);
    layout->addWidget(d.titleBar);
    layout->addWidget(d.splitter);
    layout->addWidget(d.textInput);
    layout->setStretchFactor(d.splitter, 1);

    d.splitter->addWidget(d.textBrowser);
    d.splitter->addWidget(d.listView);
    d.splitter->setStretchFactor(0, 1);

    connect(d.listView, SIGNAL(queried(QString)), this, SLOT(query(QString)));
    connect(d.textBrowser, SIGNAL(queried(QString)), this, SLOT(query(QString)));
}

BufferView::~BufferView()
{
    emit destroyed(this);
}

IrcBuffer* BufferView::buffer() const
{
    return d.buffer;
}

ListView* BufferView::listView() const
{
    return d.listView;
}

TextInput* BufferView::textInput() const
{
    return d.textInput;
}

TitleBar* BufferView::titleBar() const
{
    return d.titleBar;
}

TextBrowser* BufferView::textBrowser() const
{
    return d.textBrowser;
}

void BufferView::setBuffer(IrcBuffer* buffer)
{
    if (d.buffer != buffer) {
        d.buffer = buffer;

        IrcChannel* channel = qobject_cast<IrcChannel*>(buffer);
        d.listView->setChannel(channel);
        d.listView->setVisible(channel);

        d.titleBar->setBuffer(buffer);
        d.textInput->setBuffer(buffer);
        if (buffer) {
            QWidget* focus = qApp->focusWidget();
            if (!focus || !focus->inherits("QLineEdit") || (focus->inherits("TextInput") && !isAncestorOf(focus)))
                d.textInput->setFocus();

            TextDocument* doc = 0;
            QList<TextDocument*> documents = d.buffer->findChildren<TextDocument*>();
            // there might be multiple clones, but at least one instance
            // must always remain there to avoid losing history...
            Q_ASSERT(!documents.isEmpty());
            foreach (TextDocument* d, documents) {
                if (!d->isVisible())
                    doc = d;
            }
            if (!doc) {
                doc = documents.first()->clone();
                emit cloned(doc);
            }
            d.textBrowser->setDocument(doc);
        }

        emit bufferChanged(buffer);
    }
}

void BufferView::closeBuffer()
{
    if (d.buffer)
        emit bufferClosed(d.buffer);
}

void BufferView::query(const QString& user)
{
    IrcBufferModel* model = d.buffer ? d.buffer->model() : 0;
    if (model)
        setBuffer(model->add(user));
}
<commit_msg>BufferView: fix uninitialized variable<commit_after>/*
 * Copyright (C) 2008-2013 The Communi Project
 *
 * This example is free, and not covered by the LGPL license. There is no
 * restriction applied to their modification, redistribution, using and so on.
 * You can study them, modify them, use them in your own program - either
 * completely or partially.
 */

#include "bufferview.h"
#include "textdocument.h"
#include "textbrowser.h"
#include "textinput.h"
#include "listview.h"
#include "titlebar.h"
#include <IrcBufferModel>
#include <QApplication>
#include <QVBoxLayout>
#include <IrcChannel>
#include <IrcBuffer>

BufferView::BufferView(QWidget* parent) : QWidget(parent)
{
    d.buffer = 0;

    d.titleBar = new TitleBar(this);
    d.listView = new ListView(this);
    d.textInput = new TextInput(this);
    d.textBrowser = new TextBrowser(this);
    d.textBrowser->setBuddy(d.textInput);

    d.splitter = new QSplitter(this);
    d.splitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);

    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->setSpacing(0);
    layout->setMargin(0);
    layout->addWidget(d.titleBar);
    layout->addWidget(d.splitter);
    layout->addWidget(d.textInput);
    layout->setStretchFactor(d.splitter, 1);

    d.splitter->addWidget(d.textBrowser);
    d.splitter->addWidget(d.listView);
    d.splitter->setStretchFactor(0, 1);

    connect(d.listView, SIGNAL(queried(QString)), this, SLOT(query(QString)));
    connect(d.textBrowser, SIGNAL(queried(QString)), this, SLOT(query(QString)));
}

BufferView::~BufferView()
{
    emit destroyed(this);
}

IrcBuffer* BufferView::buffer() const
{
    return d.buffer;
}

ListView* BufferView::listView() const
{
    return d.listView;
}

TextInput* BufferView::textInput() const
{
    return d.textInput;
}

TitleBar* BufferView::titleBar() const
{
    return d.titleBar;
}

TextBrowser* BufferView::textBrowser() const
{
    return d.textBrowser;
}

void BufferView::setBuffer(IrcBuffer* buffer)
{
    if (d.buffer != buffer) {
        d.buffer = buffer;

        IrcChannel* channel = qobject_cast<IrcChannel*>(buffer);
        d.listView->setChannel(channel);
        d.listView->setVisible(channel);

        d.titleBar->setBuffer(buffer);
        d.textInput->setBuffer(buffer);
        if (buffer) {
            QWidget* focus = qApp->focusWidget();
            if (!focus || !focus->inherits("QLineEdit") || (focus->inherits("TextInput") && !isAncestorOf(focus)))
                d.textInput->setFocus();

            TextDocument* doc = 0;
            QList<TextDocument*> documents = d.buffer->findChildren<TextDocument*>();
            // there might be multiple clones, but at least one instance
            // must always remain there to avoid losing history...
            Q_ASSERT(!documents.isEmpty());
            foreach (TextDocument* d, documents) {
                if (!d->isVisible())
                    doc = d;
            }
            if (!doc) {
                doc = documents.first()->clone();
                emit cloned(doc);
            }
            d.textBrowser->setDocument(doc);
        }

        emit bufferChanged(buffer);
    }
}

void BufferView::closeBuffer()
{
    if (d.buffer)
        emit bufferClosed(d.buffer);
}

void BufferView::query(const QString& user)
{
    IrcBufferModel* model = d.buffer ? d.buffer->model() : 0;
    if (model)
        setBuffer(model->add(user));
}
<|endoftext|>