<commit_before>/******************************************************************************\
* File:          app.cpp
* Purpose:       Implementation of wxExApp class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/config.h>
#include <wx/dir.h>
#include <wx/stdpaths.h>
#include <wx/extension/app.h>
#include <wx/extension/frd.h>
#include <wx/extension/lexers.h>
#include <wx/extension/log.h>
#include <wx/extension/printing.h>
#include <wx/extension/stc.h>
#include <wx/extension/tool.h>

int wxExApp::OnExit()
{
  delete wxExFindReplaceData::Set(NULL);
  delete wxExLexers::Set(NULL);
  delete wxExLog::Set(NULL);
  delete wxExPrinting::Set(NULL);
  delete wxExTool::Set(NULL);

  return wxApp::OnExit();
}

bool wxExApp::OnInit()
{
  // Init the localization, from now on things will be translated.
  // So do this before constructing config and wxExTool::Initialize, as these use localization.
  if (m_Locale.Init())
  {
    // If there are catalogs in the catalog_dir, then add them to the m_Locale.
    // README: We use the canonical name, also for windows, not sure whether that is
    // the best.
    const wxString catalogDir = wxStandardPaths::Get().GetLocalizedResourcesDir(
      m_Locale.GetCanonicalName(),
      // This seems to be necessarty for wxGTK. For wxMSW it isn't used.
      wxStandardPaths::ResourceCat_Messages);

    if (wxFileName::DirExists(catalogDir))
    {
      wxArrayString files;
      wxDir::GetAllFiles(catalogDir, &files);

      for (size_t i = 0 ; i < files.GetCount(); i++)
      {
        // Default the wxstd is already loaded by m_Locale.Init(),
        // so do not do it twice.
        const wxFileName fn(files.Item(i));

        if (!m_Locale.IsLoaded(fn.GetName()))
        {
          if (!m_Locale.AddCatalog(fn.GetName()))
          {
            wxLogError("Catalog could not be added: " + fn.GetName());
          }
        }
      }
    }
  }

  // Now construct the config, as most classes use it.
  wxConfigBase* config;
#ifdef wxExUSE_PORTABLE
  config = new wxFileConfig(
    wxEmptyString,
    wxEmptyString,
    wxFileName(
      wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(),
      GetAppName() + wxString(".cfg")).GetFullPath(),
    wxEmptyString,
    wxCONFIG_USE_LOCAL_FILE);
#else
  // As wxStandardPaths::GetUserDataDir is used, subdir is necessary for config.
  // (ignored on non-Unix system)
  config = new wxConfig(
    wxEmptyString,
    wxEmptyString,
    wxEmptyString,
    wxEmptyString,
    wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_SUBDIR);
#endif
  wxConfigBase::Set(config);

  // Finally call all available static initializers.
  wxExSTC::PathListInit();

  return wxApp::OnInit();
}
<commit_msg>added default true to SVN<commit_after>/******************************************************************************\
* File:          app.cpp
* Purpose:       Implementation of wxExApp class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/config.h>
#include <wx/dir.h>
#include <wx/stdpaths.h>
#include <wx/extension/app.h>
#include <wx/extension/frd.h>
#include <wx/extension/lexers.h>
#include <wx/extension/log.h>
#include <wx/extension/printing.h>
#include <wx/extension/stc.h>
#include <wx/extension/tool.h>

int wxExApp::OnExit()
{
  delete wxExFindReplaceData::Set(NULL);
  delete wxExLexers::Set(NULL);
  delete wxExLog::Set(NULL);
  delete wxExPrinting::Set(NULL);
  delete wxExTool::Set(NULL);

  return wxApp::OnExit();
}

bool wxExApp::OnInit()
{
  // Init the localization, from now on things will be translated.
  // So do this before constructing config and wxExTool::Initialize, as these use localization.
  if (m_Locale.Init())
  {
    // If there are catalogs in the catalog_dir, then add them to the m_Locale.
    // README: We use the canonical name, also for windows, not sure whether that is
    // the best.
    const wxString catalogDir = wxStandardPaths::Get().GetLocalizedResourcesDir(
      m_Locale.GetCanonicalName(),
      // This seems to be necessarty for wxGTK. For wxMSW it isn't used.
      wxStandardPaths::ResourceCat_Messages);

    if (wxFileName::DirExists(catalogDir))
    {
      wxArrayString files;
      wxDir::GetAllFiles(catalogDir, &files);

      for (size_t i = 0 ; i < files.GetCount(); i++)
      {
        // Default the wxstd is already loaded by m_Locale.Init(),
        // so do not do it twice.
        const wxFileName fn(files.Item(i));

        if (!m_Locale.IsLoaded(fn.GetName()))
        {
          if (!m_Locale.AddCatalog(fn.GetName()))
          {
            wxLogError("Catalog could not be added: " + fn.GetName());
          }
        }
      }
    }
  }

  // Now construct the config, as most classes use it.
  wxConfigBase* config;
#ifdef wxExUSE_PORTABLE
  config = new wxFileConfig(
    wxEmptyString,
    wxEmptyString,
    wxFileName(
      wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(),
      GetAppName() + wxString(".cfg")).GetFullPath(),
    wxEmptyString,
    wxCONFIG_USE_LOCAL_FILE);
#else
  // As wxStandardPaths::GetUserDataDir is used, subdir is necessary for config.
  // (ignored on non-Unix system)
  config = new wxConfig(
    wxEmptyString,
    wxEmptyString,
    wxEmptyString,
    wxEmptyString,
    wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_SUBDIR);
#endif
  wxConfigBase::Set(config);

  if (!wxConfigBase::Get()->Exists("SVN"))
  {
    wxConfigBase::Get()->Write("SVN", true);
  }

  // Finally call all available static initializers.
  wxExSTC::PathListInit();

  return wxApp::OnInit();
}
<|endoftext|>


<commit_before>//
//  mismatchmodel.cpp
//  express
//
//  Created by Adam Roberts on 4/23/11.
//  Copyright 2011 Adam Roberts. All rights reserved.
//

#include "main.h"
#include "mismatchmodel.h"
#include "targets.h"
#include "fragments.h"
#include "sequence.h"
#include <iostream>
#include <fstream>

using namespace std;

MismatchTable::MismatchTable(double alpha)
: _first_read_mm(MAX_READ_LEN, FrequencyMatrix<double>(16, 4, alpha)),
  _second_read_mm(MAX_READ_LEN, FrequencyMatrix<double>(16, 4, alpha)),
  _insert_params(1, MAX_READ_LEN, alpha),
  _delete_params(1, MAX_READ_LEN, alpha),
  _max_len(0),
  _active(false)
{}

double MismatchTable::log_likelihood(const FragHit& f) const
{
    if (!_active)
        return 0;

    const Target& targ = *f.mapped_targ;
    const Sequence& t_seq_fwd = targ.seq(0);
    const Sequence& t_seq_rev = targ.seq(1);

    double ll = 0;

    const vector<FrequencyMatrix<double> >& left_mm = (f.left_first) ? _first_read_mm : _second_read_mm;
    const vector<FrequencyMatrix<double> >& right_mm = (!f.left_first) ? _first_read_mm : _second_read_mm;

    size_t cur;
    size_t ref;
    size_t prev;
    size_t index;

    size_t i = 0; // read index
    size_t j = f.left; // genomic index

    size_t del_len = 0;
    vector<Indel>::const_iterator ins = f.inserts_l.begin();
    vector<Indel>::const_iterator del = f.deletes_l.begin();

    while (i < f.seq_l.length())
    {
        if (del != f.deletes_l.end() && del->pos == i)
        {
            ll += _delete_params(del->len);
            j += del->len;
            del_len = del->len;
            del++;
        }
        else if (ins != f.inserts_l.end() && ins->pos == i)
        {
            ll += _insert_params(ins->len);
            i += ins->len;
            if (ins->len > del_len)
                ll += (ins->len-del_len)*_delete_params(0); //FIX: Assymetric
            del_len = 0;
            ins++;
        }
        else
        {
            if (del_len > 0)
                ll += _delete_params(0);
            del_len = 0;
            ll += _insert_params(0);

            cur = f.seq_l[i];
            prev = (i) ? f.seq_l[i-1] : 0;

            if (t_seq_fwd.prob())
            {
                for(size_t nuc = 0; nuc < NUM_NUCS; nuc++)
                {
                    index = (prev << 2) + nuc;
                    ll += t_seq_fwd.get_prob(j, nuc) + left_mm[i](index, cur);
                }
            }
            else
            {
                ref = t_seq_fwd[j];
                index = (prev << 2) + ref;
                ll += left_mm[i](index, cur);
            }

            i++;
            j++;
        }
    }

    size_t r_len = f.seq_r.length();
    i = 0;
    j = targ.length()-f.right;
    ins = f.inserts_r.end()-1;
    del = f.deletes_r.end()-1;

    while (i < r_len)
    {
        if (del != f.deletes_r.begin()-1 && del->pos == r_len-i)
        {
            ll += _delete_params(del->len);
            j += del->len;
            del_len = del->len;
            del--;
        }
        else if (ins != f.inserts_r.begin()-1 && ins->pos + ins->len == r_len-i)
        {
            ll += _insert_params(ins->len);
            if (ins->len > del_len)
                ll += (ins->len-del_len)*_delete_params(0);
            del_len = 0;

            i += ins->len;
            ins--;
        }
        else
        {
            if (del_len > 0)
                ll += _delete_params(0);
            del_len = 0;
            ll += _insert_params(0);

            cur = f.seq_r[i];
            prev = (i) ? f.seq_r[i-1] : 0;

            if (t_seq_rev.prob())
            {
                for(size_t nuc = 0; nuc < NUM_NUCS; nuc++)
                {
                    index = (prev << 2) + nuc;
                    ll += t_seq_rev.get_prob(j, nuc) + right_mm[i](index, cur);
                }
            }
            else
            {
                ref = t_seq_rev[j];
                index = (prev << 2) + ref;
                ll += right_mm[i](index, cur);
            }

            i++;
            j++;
        }
    }

    assert(!(isnan(ll)||isinf(ll)));
    return ll;
}

void MismatchTable::update(const FragHit& f, double p, double mass)
{
    Target& targ = *f.mapped_targ;
    Sequence& t_seq_fwd = targ.seq(0);
    Sequence& t_seq_rev = targ.seq(1);

    vector<FrequencyMatrix<double> >& left_mm = (f.left_first) ? _first_read_mm : _second_read_mm;
    vector<FrequencyMatrix<double> >& right_mm = (!f.left_first) ? _first_read_mm : _second_read_mm;

    size_t cur;
    size_t ref;
    size_t prev;
    size_t index;

    size_t i = 0; // read index
    size_t j = f.left; // genomic index

    size_t del_len = 0;
    vector<Indel>::const_iterator ins = f.inserts_l.begin();
    vector<Indel>::const_iterator del = f.deletes_l.begin();

    while (i < f.seq_l.length())
    {
        if (del != f.deletes_l.end() && del->pos == i)
        {
            _delete_params.increment(del->len, mass);
            j += del->len;
            del_len = del->len;
            del++;
        }
        else if (ins != f.inserts_l.end() && ins->pos == i)
        {
            _insert_params.increment(ins->len, mass);
            i += ins->len;
            if (ins->len > del_len)
                _delete_params.increment(0, mass); //FIX: Assymetric
            del_len = 0;
            ins++;
        }
        else
        {
            if (del_len > 0)
                _delete_params.increment(0, mass);
            del_len = 0;
            _insert_params.increment(0, mass);

            cur = f.seq_l[i];
            prev = (i) ? f.seq_l[i-1] : 0;
            ref = t_seq_fwd[j];

            if (t_seq_fwd.prob())
            {
                size_t ref_index = (prev << 2) + ref;
                for(size_t nuc = 0; nuc < NUM_NUCS; nuc++)
                {
                    index = (prev << 2) + nuc;
                    left_mm[i].increment(index, cur, mass+p+t_seq_fwd.get_prob(j, nuc));

                    t_seq_rev.update_exp(j, nuc, p+right_mm[i](ref_index, nuc));
                }
                t_seq_fwd.update_obs(j, cur, p);
            }
            else
            {
                index = (prev << 2) + ref;
                left_mm[i].increment(index, cur, mass+p);
            }

            i++;
            j++;
        }
    }

    size_t r_len = f.seq_r.length();
    i = 0;
    j = targ.length()-f.right;
    ins = f.inserts_r.end()-1;
    del = f.deletes_r.end()-1;

    while (i < r_len)
    {
        if (del != f.deletes_r.begin()-1 && del->pos == r_len-i )
        {
            _delete_params.increment(del->len, mass);
            j += del->len;
            del_len = del->len;
            del--;
        }
        else if (ins != f.inserts_r.begin()-1 && ins->pos + ins->len == r_len-i)
        {
            _insert_params.increment(ins->len, mass);
            if (ins->len > del_len)
                _delete_params.increment(0, mass);
            del_len = 0;

            i += ins->len;
            ins--;
        }
        else
        {
            if (del_len > 0)
                _delete_params.increment(0, mass);
            del_len = 0;
            _insert_params.increment(0, mass);

            cur = f.seq_r[i];
            prev = (i) ? f.seq_r[i-1] : 0;
            ref = t_seq_rev[j];

            if (t_seq_rev.prob())
            {
                size_t ref_index = (prev << 2) + ref;
                for(size_t nuc = 0; nuc < NUM_NUCS; nuc++)
                {
                    index = (prev << 2) + nuc;
                    right_mm[i].increment(index, cur, mass+p+t_seq_rev.get_prob(j, nuc));

                    t_seq_rev.update_exp(j, nuc, p+right_mm[i](ref_index, nuc));
                }
                t_seq_rev.update_obs(j, cur, p);
            }
            else
            {
                index = (prev << 2) + ref;
                right_mm[i].increment(index, cur, mass+p);
            }
            i++;
            j++;
        }
    }

    _max_len = max(_max_len, max(f.seq_l.length(), f.seq_r.length()));
}

string MismatchTable::to_string() const
{
    string s = "";
    char buff[50];

    for (size_t ref = 0; ref < NUM_NUCS; ref++)
    {
        vector<double> mass(4, HUGE_VAL);
        double tot = HUGE_VAL;
        for (size_t prev = 0; prev < NUM_NUCS; prev++)
        {
            size_t col_i = (prev << 2) + ref;
            for (size_t obs = 0; obs < NUM_NUCS; obs++)
            {
                size_t arr_i = (col_i << 2) + obs;
                for (size_t k = 0; k < MAX_READ_LEN; k++)
                {
                    double val = _first_read_mm[k].arr(arr_i);
                    mass[obs] = log_sum(mass[obs], val);
                    tot = log_sum(tot, val);
                }
            }
        }
        for (size_t obs = 0; obs < NUM_NUCS; obs++)
        {
            sprintf(buff, "%e ", sexp(mass[obs]-tot));
            s += buff;
        }
    }

    s.erase(s.length()-1,1);
    return s;
}

void MismatchTable::append_output(ofstream& outfile) const
{
    string col_header =  "\t";
    for(size_t i = 0; i < 64; i++)
    {
        col_header += NUCS[i>>4];
        col_header += NUCS[i>>2 & 3];
        col_header += "->*";
        col_header += NUCS[i & 3];
        col_header += '\t';
    }
    col_header[col_header.length()-1] = '\n';

    outfile<<">First Read Mismatch\n" << col_header;
    for(size_t k = 0; k < _max_len; k++)
    {
        outfile << k << ":\t";
        for(size_t i = 0; i < 16; i++)
        {
            for (size_t j = 0; j < 4; j++)
            {
                if (k || i < 4)
                    outfile << scientific << sexp(_first_read_mm[k](i,j))<<"\t";
                else
                    outfile << scientific << 0.0 << "\t";
            }
        }
        outfile<<endl;
    }

    outfile<<">Second Read Mismatch\n" << col_header;
    for(size_t k = 0; k < _max_len; k++)
    {
        outfile << k << ":\t";
        for(size_t i = 0; i < 16; i++)
        {
            for (size_t j = 0; j < 4; j++)
            {
                if (k || i < 4)
                    outfile << scientific << sexp(_second_read_mm[k](i,j))<<"\t";
                else
                    outfile << scientific << 0.0 << "\t";
            }
        }
        outfile<<endl;
    }
}<commit_msg>Fixed mm ll calc<commit_after>//
//  mismatchmodel.cpp
//  express
//
//  Created by Adam Roberts on 4/23/11.
//  Copyright 2011 Adam Roberts. All rights reserved.
//

#include "main.h"
#include "mismatchmodel.h"
#include "targets.h"
#include "fragments.h"
#include "sequence.h"
#include <iostream>
#include <fstream>

using namespace std;

MismatchTable::MismatchTable(double alpha)
: _first_read_mm(MAX_READ_LEN, FrequencyMatrix<double>(16, 4, alpha)),
  _second_read_mm(MAX_READ_LEN, FrequencyMatrix<double>(16, 4, alpha)),
  _insert_params(1, MAX_READ_LEN, alpha),
  _delete_params(1, MAX_READ_LEN, alpha),
  _max_len(0),
  _active(false)
{}

double MismatchTable::log_likelihood(const FragHit& f) const
{
    if (!_active)
        return 0;

    const Target& targ = *f.mapped_targ;
    const Sequence& t_seq_fwd = targ.seq(0);
    const Sequence& t_seq_rev = targ.seq(1);

    double ll = 0;

    const vector<FrequencyMatrix<double> >& left_mm = (f.left_first) ? _first_read_mm : _second_read_mm;
    const vector<FrequencyMatrix<double> >& right_mm = (!f.left_first) ? _first_read_mm : _second_read_mm;

    size_t cur;
    size_t ref;
    size_t prev;
    size_t index;

    size_t i = 0; // read index
    size_t j = f.left; // genomic index

    size_t del_len = 0;
    vector<Indel>::const_iterator ins = f.inserts_l.begin();
    vector<Indel>::const_iterator del = f.deletes_l.begin();

    while (i < f.seq_l.length())
    {
        if (del != f.deletes_l.end() && del->pos == i)
        {
            ll += _delete_params(del->len);
            j += del->len;
            del_len = del->len;
            del++;
        }
        else if (ins != f.inserts_l.end() && ins->pos == i)
        {
            ll += _insert_params(ins->len);
            i += ins->len;
            if (ins->len > del_len)
                ll += (ins->len-del_len)*_delete_params(0); //FIX: Assymetric
            del_len = 0;
            ins++;
        }
        else
        {
            if (del_len > 0)
                ll += _delete_params(0);
            del_len = 0;
            ll += _insert_params(0);

            cur = f.seq_l[i];
            prev = (i) ? f.seq_l[i-1] : 0;

            if (t_seq_fwd.prob())
            {
                double trans_prob = HUGE_VAL;
                for(size_t nuc = 0; nuc < NUM_NUCS; nuc++)
                {
                    index = (prev << 2) + nuc;
                    trans_prob = log_sum(trans_prob, t_seq_fwd.get_prob(j, nuc) + left_mm[i](index, cur));
                }
                ll += trans_prob;
            }
            else
            {
                ref = t_seq_fwd[j];
                index = (prev << 2) + ref;
                ll += left_mm[i](index, cur);
            }

            i++;
            j++;
        }
    }

    size_t r_len = f.seq_r.length();
    i = 0;
    j = targ.length()-f.right;
    ins = f.inserts_r.end()-1;
    del = f.deletes_r.end()-1;

    while (i < r_len)
    {
        if (del != f.deletes_r.begin()-1 && del->pos == r_len-i)
        {
            ll += _delete_params(del->len);
            j += del->len;
            del_len = del->len;
            del--;
        }
        else if (ins != f.inserts_r.begin()-1 && ins->pos + ins->len == r_len-i)
        {
            ll += _insert_params(ins->len);
            if (ins->len > del_len)
                ll += (ins->len-del_len)*_delete_params(0);
            del_len = 0;

            i += ins->len;
            ins--;
        }
        else
        {
            if (del_len > 0)
                ll += _delete_params(0);
            del_len = 0;
            ll += _insert_params(0);

            cur = f.seq_r[i];
            prev = (i) ? f.seq_r[i-1] : 0;

            if (t_seq_rev.prob())
            {
                double trans_prob = HUGE_VAL;
                for(size_t nuc = 0; nuc < NUM_NUCS; nuc++)
                {
                    index = (prev << 2) + nuc;
                    trans_prob = log_sum(trans_prob, t_seq_rev.get_prob(j, nuc) + right_mm[i](index, cur));
                }
                ll += trans_prob;
            }
            else
            {
                ref = t_seq_rev[j];
                index = (prev << 2) + ref;
                ll += right_mm[i](index, cur);
            }

            i++;
            j++;
        }
    }

    assert(!(isnan(ll)||isinf(ll)));
    return ll;
}

void MismatchTable::update(const FragHit& f, double p, double mass)
{
    Target& targ = *f.mapped_targ;
    Sequence& t_seq_fwd = targ.seq(0);
    Sequence& t_seq_rev = targ.seq(1);

    vector<FrequencyMatrix<double> >& left_mm = (f.left_first) ? _first_read_mm : _second_read_mm;
    vector<FrequencyMatrix<double> >& right_mm = (!f.left_first) ? _first_read_mm : _second_read_mm;

    size_t cur;
    size_t ref;
    size_t prev;
    size_t index;

    size_t i = 0; // read index
    size_t j = f.left; // genomic index

    size_t del_len = 0;
    vector<Indel>::const_iterator ins = f.inserts_l.begin();
    vector<Indel>::const_iterator del = f.deletes_l.begin();

    while (i < f.seq_l.length())
    {
        if (del != f.deletes_l.end() && del->pos == i)
        {
            _delete_params.increment(del->len, mass);
            j += del->len;
            del_len = del->len;
            del++;
        }
        else if (ins != f.inserts_l.end() && ins->pos == i)
        {
            _insert_params.increment(ins->len, mass);
            i += ins->len;
            if (ins->len > del_len)
                _delete_params.increment(0, mass); //FIX: Assymetric
            del_len = 0;
            ins++;
        }
        else
        {
            if (del_len > 0)
                _delete_params.increment(0, mass);
            del_len = 0;
            _insert_params.increment(0, mass);

            cur = f.seq_l[i];
            prev = (i) ? f.seq_l[i-1] : 0;
            ref = t_seq_fwd[j];

            if (t_seq_fwd.prob())
            {
                size_t ref_index = (prev << 2) + ref;
                for(size_t nuc = 0; nuc < NUM_NUCS; nuc++)
                {
                    index = (prev << 2) + nuc;
                    left_mm[i].increment(index, cur, mass+p+t_seq_fwd.get_prob(j, nuc));

                    t_seq_rev.update_exp(j, nuc, p+right_mm[i](ref_index, nuc));
                }
                t_seq_fwd.update_obs(j, cur, p);
            }
            else
            {
                index = (prev << 2) + ref;
                left_mm[i].increment(index, cur, mass+p);
            }

            i++;
            j++;
        }
    }

    size_t r_len = f.seq_r.length();
    i = 0;
    j = targ.length()-f.right;
    ins = f.inserts_r.end()-1;
    del = f.deletes_r.end()-1;

    while (i < r_len)
    {
        if (del != f.deletes_r.begin()-1 && del->pos == r_len-i )
        {
            _delete_params.increment(del->len, mass);
            j += del->len;
            del_len = del->len;
            del--;
        }
        else if (ins != f.inserts_r.begin()-1 && ins->pos + ins->len == r_len-i)
        {
            _insert_params.increment(ins->len, mass);
            if (ins->len > del_len)
                _delete_params.increment(0, mass);
            del_len = 0;

            i += ins->len;
            ins--;
        }
        else
        {
            if (del_len > 0)
                _delete_params.increment(0, mass);
            del_len = 0;
            _insert_params.increment(0, mass);

            cur = f.seq_r[i];
            prev = (i) ? f.seq_r[i-1] : 0;
            ref = t_seq_rev[j];

            if (t_seq_rev.prob())
            {
                size_t ref_index = (prev << 2) + ref;
                for(size_t nuc = 0; nuc < NUM_NUCS; nuc++)
                {
                    index = (prev << 2) + nuc;
                    right_mm[i].increment(index, cur, mass+p+t_seq_rev.get_prob(j, nuc));

                    t_seq_rev.update_exp(j, nuc, p+right_mm[i](ref_index, nuc));
                }
                t_seq_rev.update_obs(j, cur, p);
            }
            else
            {
                index = (prev << 2) + ref;
                right_mm[i].increment(index, cur, mass+p);
            }
            i++;
            j++;
        }
    }

    _max_len = max(_max_len, max(f.seq_l.length(), f.seq_r.length()));
}

string MismatchTable::to_string() const
{
    string s = "";
    char buff[50];

    for (size_t ref = 0; ref < NUM_NUCS; ref++)
    {
        vector<double> mass(4, HUGE_VAL);
        double tot = HUGE_VAL;
        for (size_t prev = 0; prev < NUM_NUCS; prev++)
        {
            size_t col_i = (prev << 2) + ref;
            for (size_t obs = 0; obs < NUM_NUCS; obs++)
            {
                size_t arr_i = (col_i << 2) + obs;
                for (size_t k = 0; k < MAX_READ_LEN; k++)
                {
                    double val = _first_read_mm[k].arr(arr_i);
                    mass[obs] = log_sum(mass[obs], val);
                    tot = log_sum(tot, val);
                }
            }
        }
        for (size_t obs = 0; obs < NUM_NUCS; obs++)
        {
            sprintf(buff, "%e ", sexp(mass[obs]-tot));
            s += buff;
        }
    }

    s.erase(s.length()-1,1);
    return s;
}

void MismatchTable::append_output(ofstream& outfile) const
{
    string col_header =  "\t";
    for(size_t i = 0; i < 64; i++)
    {
        col_header += NUCS[i>>4];
        col_header += NUCS[i>>2 & 3];
        col_header += "->*";
        col_header += NUCS[i & 3];
        col_header += '\t';
    }
    col_header[col_header.length()-1] = '\n';

    outfile<<">First Read Mismatch\n" << col_header;
    for(size_t k = 0; k < _max_len; k++)
    {
        outfile << k << ":\t";
        for(size_t i = 0; i < 16; i++)
        {
            for (size_t j = 0; j < 4; j++)
            {
                if (k || i < 4)
                    outfile << scientific << sexp(_first_read_mm[k](i,j))<<"\t";
                else
                    outfile << scientific << 0.0 << "\t";
            }
        }
        outfile<<endl;
    }

    outfile<<">Second Read Mismatch\n" << col_header;
    for(size_t k = 0; k < _max_len; k++)
    {
        outfile << k << ":\t";
        for(size_t i = 0; i < 16; i++)
        {
            for (size_t j = 0; j < 4; j++)
            {
                if (k || i < 4)
                    outfile << scientific << sexp(_second_read_mm[k](i,j))<<"\t";
                else
                    outfile << scientific << 0.0 << "\t";
            }
        }
        outfile<<endl;
    }
}<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/MetaProcessor/MetaProcessor.h"

#include "Display.h"
#include "InputValidator.h"
#include "MetaParser.h"
#include "MetaSema.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"

#include "clang/Basic/FileManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/Support/Path.h"

#include <fstream>
#include <cstdlib>
#include <cctype>
#include <stdio.h>
#ifndef WIN32
#include <unistd.h>
#else
#include <io.h>
#define STDIN_FILENO  0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif

using namespace clang;

namespace cling {

  MetaProcessor::MaybeRedirectOutputRAII::MaybeRedirectOutputRAII(
                                          MetaProcessor* p)
  :m_MetaProcessor(p), m_isCurrentlyRedirecting(0) {
    StringRef redirectionFile;
    if (!m_MetaProcessor->m_PrevStdoutFileName.empty()) {
      redirectionFile = m_MetaProcessor->m_PrevStdoutFileName.back();
      redirect(stdout, redirectionFile.str(), kSTDOUT);
    }
    if (!m_MetaProcessor->m_PrevStderrFileName.empty()) {
      redirectionFile = m_MetaProcessor->m_PrevStderrFileName.back();
      // Deal with the case 2>&1 and 2&>1
      if (strcmp(redirectionFile.data(), "_IO_2_1_stdout_") == 0) {
        // If out is redirected to a file.
        if (!m_MetaProcessor->m_PrevStdoutFileName.empty()) {
          redirectionFile = m_MetaProcessor->m_PrevStdoutFileName.back();
        } else {
          unredirect(m_MetaProcessor->m_backupFDStderr, STDERR_FILENO, stderr);
        }
      }
      redirect(stderr, redirectionFile.str(), kSTDERR);
    }
  }

  void MetaProcessor::MaybeRedirectOutputRAII::redirect(FILE* file,
                                        const std::string& fileName,
                                        MetaProcessor::RedirectionScope scope) {
    if (!fileName.empty()) {
      FILE* redirectionFile = freopen(fileName.c_str(), "a", file);
      if (!redirectionFile) {
        llvm::errs()<<"cling::MetaProcessor::MaybeRedirectOutputRAII::redirect:"
                    " Not succefully reopened the redirection file "
                    << fileName.c_str() << "\n.";
      } else {
        m_isCurrentlyRedirecting |= scope;
      }
    }
  }

  void MetaProcessor::MaybeRedirectOutputRAII::pop() {
    if (m_isCurrentlyRedirecting & kSTDOUT) {
      unredirect(m_MetaProcessor->m_backupFDStdout, STDOUT_FILENO, stdout);
    }
    if (m_isCurrentlyRedirecting & kSTDERR) {
      unredirect(m_MetaProcessor->m_backupFDStderr, STDERR_FILENO, stderr);
    }
  }

  void MetaProcessor::MaybeRedirectOutputRAII::unredirect(int backupFD,
                                                          int expectedFD,
                                                          FILE* file) {
    // Switch back to previous file after line is processed.

    // Flush the current content if there is any.
    if (!feof(file)) {
      fflush(file);
    }
    // Copy the original fd for the std.
    if (dup2(backupFD, expectedFD) != expectedFD) {
        llvm::errs() << "cling::MetaProcessor::unredirect "
                     << "The unredirection file descriptor not valid "
                     << backupFD << ".\n";
    }
  }

  MetaProcessor::MetaProcessor(Interpreter& interp, raw_ostream& outs)
    : m_Interp(interp), m_Outs(&outs) {
    m_InputValidator.reset(new InputValidator());
    m_MetaParser.reset(new MetaParser(new MetaSema(interp, *this)));
    m_backupFDStdout = copyFileDescriptor(STDOUT_FILENO);
    m_backupFDStderr = copyFileDescriptor(STDERR_FILENO);
  }

  MetaProcessor::~MetaProcessor() {}

  int MetaProcessor::process(const char* input_text,
                             Interpreter::CompilationResult& compRes,
                             Value* result) {
    if (result)
      *result = Value();
    compRes = Interpreter::kSuccess;
    int expectedIndent = m_InputValidator->getExpectedIndent();

    if (expectedIndent)
      compRes = Interpreter::kMoreInputExpected;
    if (!input_text || !input_text[0]) {
      // nullptr / empty string, nothing to do.
      return expectedIndent;
    }
    std::string input_line(input_text);
    if (input_line == "\n") { // just a blank line, nothing to do.
      return expectedIndent;
    }
    //  Check for and handle meta commands.
    m_MetaParser->enterNewInputLine(input_line);
    MetaSema::ActionResult actionResult = MetaSema::AR_Success;
    if (m_MetaParser->isMetaCommand(actionResult, result)) {

      if (m_MetaParser->isQuitRequested())
        return -1;

      if (actionResult != MetaSema::AR_Success)
        compRes = Interpreter::kFailure;
       // ExpectedIndent might have changed after meta command.
       return m_InputValidator->getExpectedIndent();
    }

    // Check if the current statement is now complete. If not, return to
    // prompt for more.
    if (m_InputValidator->validate(input_line) == InputValidator::kIncomplete) {
      compRes = Interpreter::kMoreInputExpected;
      return m_InputValidator->getExpectedIndent();
    }

    //  We have a complete statement, compile and execute it.
    std::string input = m_InputValidator->getInput();
    m_InputValidator->reset();
    // if (m_Options.RawInput)
    //   compResLocal = m_Interp.declare(input);
    // else
    compRes = m_Interp.process(input, result);

    return 0;
  }

  void MetaProcessor::cancelContinuation() const {
    m_InputValidator->reset();
  }

  int MetaProcessor::getExpectedIndent() const {
    return m_InputValidator->getExpectedIndent();
  }

  Interpreter::CompilationResult
  MetaProcessor::readInputFromFile(llvm::StringRef filename,
                                   Value* result,
                                   bool ignoreOutmostBlock /*=false*/) {

    {
      // check that it's not binary:
      std::ifstream in(filename.str().c_str(), std::ios::in | std::ios::binary);
      char magic[1024] = {0};
      in.read(magic, sizeof(magic));
      size_t readMagic = in.gcount();
      if (readMagic >= 4) {
        llvm::StringRef magicStr(magic,in.gcount());
        llvm::sys::fs::file_magic fileType
          = llvm::sys::fs::identify_magic(magicStr);
        if (fileType != llvm::sys::fs::file_magic::unknown) {
          llvm::errs() << "Error in cling::MetaProcessor: "
            "cannot read input from a binary file!\n";
          return Interpreter::kFailure;
        }
        unsigned printable = 0;
        for (size_t i = 0; i < readMagic; ++i)
          if (isprint(magic[i]))
            ++printable;
        if (10 * printable <  5 * readMagic) {
          // 50% printable for ASCII files should be a safe guess.
          llvm::errs() << "Error in cling::MetaProcessor: "
            "cannot read input from a (likely) binary file!\n" << printable;
          return Interpreter::kFailure;
        }
      }
    }

    std::ifstream in(filename.str().c_str());
    in.seekg(0, std::ios::end);
    size_t size = in.tellg();
    std::string content(size, ' ');
    in.seekg(0);
    in.read(&content[0], size);

    if (ignoreOutmostBlock && !content.empty()) {
      static const char whitespace[] = " \t\r\n";
      std::string::size_type posNonWS = content.find_first_not_of(whitespace);
      // Handle comments before leading {
      while (content[posNonWS] == '/' && content[posNonWS+1] == '/') {
        // Remove the comment line
        posNonWS = content.find_first_of('\n', posNonWS+2)+1;
      }
      std::string::size_type replaced = posNonWS;
      if (posNonWS != std::string::npos) {
        if (content[posNonWS] == '{') {
          // hide the curly brace:
          content[posNonWS] = ' ';
          // and the matching closing '}'
          posNonWS = content.find_last_not_of(whitespace);
          if (posNonWS != std::string::npos) {
            if (content[posNonWS] == ';' && content[posNonWS-1] == '}') {
              content[posNonWS--] = ' '; // replace ';' and enter next if
            }
            if (content[posNonWS] == '}') {
              content[posNonWS] = ' '; // replace '}'
            } else {
              std::string::size_type posBlockClose = content.find_last_of('}');
              if (posBlockClose != std::string::npos) {
                content[posBlockClose] = ' '; // replace '}'
              }
              std::string::size_type posComment
                = content.find_first_not_of(whitespace, posComment);
              if (posComment != std::string::npos) {
                if (content[posComment] == '/' && content[posComment+1] == '/') {
                  // More text (comments) are okay after the last '}', but
                  // we can not easily find it to remove it (so we need to upgrade
                  // this code to better handle the case with comments or
                  // preprocessor code before and after the leading { and
                  // trailing })
                  while (posComment <= posNonWS) {
                    content[posComment++] = ' '; // replace '}' and comment
                  }
                } else {
                  content[replaced] = '{';
                  // By putting the '{' back, we keep the code as consistent as
                  // the user wrote it ... but we should still warn that we not
                  // goint to treat this file an unamed macro.
                  llvm::errs()
                  << "Warning in cling::MetaProcessor: can not find the closing '}', "
                  << llvm::sys::path::filename(filename)
                  << " is not handled as an unamed script!\n";
                } // did not find '}''
              } // no whitespace
            } // remove comments after the trailing '}'
          } // find '}'
        } // have '{'
      } // have non-whitespace
    } // ignore outmost block

    std::string strFilename(filename.str());
    m_CurrentlyExecutingFile = strFilename;
    bool topmost = !m_TopExecutingFile.data();
    if (topmost)
      m_TopExecutingFile = m_CurrentlyExecutingFile;
    Interpreter::CompilationResult ret;
    // We don't want to value print the results of a unnamed macro.
    content = "#line 2 \"" + filename.str() + "\" \n" + content;
    if (process((content + ";").c_str(), ret, result)) {
      // Input file has to be complete.
       llvm::errs()
          << "Error in cling::MetaProcessor: file "
          << llvm::sys::path::filename(filename)
          << " is incomplete (missing parenthesis or similar)!\n";
      ret = Interpreter::kFailure;
    }
    m_CurrentlyExecutingFile = llvm::StringRef();
    if (topmost)
      m_TopExecutingFile = llvm::StringRef();
    return ret;
  }

  void MetaProcessor::setFileStream(llvm::StringRef file, bool append, int fd,
              llvm::SmallVector<llvm::SmallString<128>, 2>& prevFileStack) {
    // If we have a fileName to redirect to store it.
    if (!file.empty()) {
      prevFileStack.push_back(file);
      // pop and push a null terminating 0.
      // SmallVectorImpl<T> does not have a c_str(), thus instead of casting to
      // a SmallString<T> we null terminate the data that we have and pop the
      // 0 char back.
      prevFileStack.back().push_back(0);
      prevFileStack.back().pop_back();
      if (!append) {
        FILE * f;
        if (!(f = fopen(file.data(), "w"))) {
          llvm::errs() << "cling::MetaProcessor::setFileStream:"
                       " The file path " << file.data() << "is not valid.";
        } else {
          fclose(f);
        }
      }
    // Else unredirection, so switch to the previous file.
    } else {
      // If there is no previous file on the stack we pop the file
      if (!prevFileStack.empty()) {
        prevFileStack.pop_back();
      }
    }
  }

  void MetaProcessor::setStdStream(llvm::StringRef file,
                                   RedirectionScope stream, bool append) {

    if (stream & kSTDOUT) {
      setFileStream(file, append, STDOUT_FILENO, m_PrevStdoutFileName);
    }
    if (stream & kSTDERR) {
      setFileStream(file, append, STDERR_FILENO, m_PrevStderrFileName);
    }
  }

  int MetaProcessor::copyFileDescriptor(int fd) {
    int backupFD = dup(fd);
    if (backupFD < 0) {
      llvm::errs() << "MetaProcessor::copyFileDescriptor: Duplicating the file"
                   " descriptor " << fd << "resulted in an error."
                   " Will not be able to unredirect.";
    }
    return backupFD;
  }

  void MetaProcessor::registerUnloadPoint(const Transaction* T,
                                          llvm::StringRef filename) {
    m_MetaParser->getActions().registerUnloadPoint(T, filename);
  }

} // end namespace cling
<commit_msg>Handle npos / not found, 2nd occurrence (Coverity 55587).<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/MetaProcessor/MetaProcessor.h"

#include "Display.h"
#include "InputValidator.h"
#include "MetaParser.h"
#include "MetaSema.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"

#include "clang/Basic/FileManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/Support/Path.h"

#include <fstream>
#include <cstdlib>
#include <cctype>
#include <stdio.h>
#ifndef WIN32
#include <unistd.h>
#else
#include <io.h>
#define STDIN_FILENO  0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif

using namespace clang;

namespace cling {

  MetaProcessor::MaybeRedirectOutputRAII::MaybeRedirectOutputRAII(
                                          MetaProcessor* p)
  :m_MetaProcessor(p), m_isCurrentlyRedirecting(0) {
    StringRef redirectionFile;
    if (!m_MetaProcessor->m_PrevStdoutFileName.empty()) {
      redirectionFile = m_MetaProcessor->m_PrevStdoutFileName.back();
      redirect(stdout, redirectionFile.str(), kSTDOUT);
    }
    if (!m_MetaProcessor->m_PrevStderrFileName.empty()) {
      redirectionFile = m_MetaProcessor->m_PrevStderrFileName.back();
      // Deal with the case 2>&1 and 2&>1
      if (strcmp(redirectionFile.data(), "_IO_2_1_stdout_") == 0) {
        // If out is redirected to a file.
        if (!m_MetaProcessor->m_PrevStdoutFileName.empty()) {
          redirectionFile = m_MetaProcessor->m_PrevStdoutFileName.back();
        } else {
          unredirect(m_MetaProcessor->m_backupFDStderr, STDERR_FILENO, stderr);
        }
      }
      redirect(stderr, redirectionFile.str(), kSTDERR);
    }
  }

  void MetaProcessor::MaybeRedirectOutputRAII::redirect(FILE* file,
                                        const std::string& fileName,
                                        MetaProcessor::RedirectionScope scope) {
    if (!fileName.empty()) {
      FILE* redirectionFile = freopen(fileName.c_str(), "a", file);
      if (!redirectionFile) {
        llvm::errs()<<"cling::MetaProcessor::MaybeRedirectOutputRAII::redirect:"
                    " Not succefully reopened the redirection file "
                    << fileName.c_str() << "\n.";
      } else {
        m_isCurrentlyRedirecting |= scope;
      }
    }
  }

  void MetaProcessor::MaybeRedirectOutputRAII::pop() {
    if (m_isCurrentlyRedirecting & kSTDOUT) {
      unredirect(m_MetaProcessor->m_backupFDStdout, STDOUT_FILENO, stdout);
    }
    if (m_isCurrentlyRedirecting & kSTDERR) {
      unredirect(m_MetaProcessor->m_backupFDStderr, STDERR_FILENO, stderr);
    }
  }

  void MetaProcessor::MaybeRedirectOutputRAII::unredirect(int backupFD,
                                                          int expectedFD,
                                                          FILE* file) {
    // Switch back to previous file after line is processed.

    // Flush the current content if there is any.
    if (!feof(file)) {
      fflush(file);
    }
    // Copy the original fd for the std.
    if (dup2(backupFD, expectedFD) != expectedFD) {
        llvm::errs() << "cling::MetaProcessor::unredirect "
                     << "The unredirection file descriptor not valid "
                     << backupFD << ".\n";
    }
  }

  MetaProcessor::MetaProcessor(Interpreter& interp, raw_ostream& outs)
    : m_Interp(interp), m_Outs(&outs) {
    m_InputValidator.reset(new InputValidator());
    m_MetaParser.reset(new MetaParser(new MetaSema(interp, *this)));
    m_backupFDStdout = copyFileDescriptor(STDOUT_FILENO);
    m_backupFDStderr = copyFileDescriptor(STDERR_FILENO);
  }

  MetaProcessor::~MetaProcessor() {}

  int MetaProcessor::process(const char* input_text,
                             Interpreter::CompilationResult& compRes,
                             Value* result) {
    if (result)
      *result = Value();
    compRes = Interpreter::kSuccess;
    int expectedIndent = m_InputValidator->getExpectedIndent();

    if (expectedIndent)
      compRes = Interpreter::kMoreInputExpected;
    if (!input_text || !input_text[0]) {
      // nullptr / empty string, nothing to do.
      return expectedIndent;
    }
    std::string input_line(input_text);
    if (input_line == "\n") { // just a blank line, nothing to do.
      return expectedIndent;
    }
    //  Check for and handle meta commands.
    m_MetaParser->enterNewInputLine(input_line);
    MetaSema::ActionResult actionResult = MetaSema::AR_Success;
    if (m_MetaParser->isMetaCommand(actionResult, result)) {

      if (m_MetaParser->isQuitRequested())
        return -1;

      if (actionResult != MetaSema::AR_Success)
        compRes = Interpreter::kFailure;
       // ExpectedIndent might have changed after meta command.
       return m_InputValidator->getExpectedIndent();
    }

    // Check if the current statement is now complete. If not, return to
    // prompt for more.
    if (m_InputValidator->validate(input_line) == InputValidator::kIncomplete) {
      compRes = Interpreter::kMoreInputExpected;
      return m_InputValidator->getExpectedIndent();
    }

    //  We have a complete statement, compile and execute it.
    std::string input = m_InputValidator->getInput();
    m_InputValidator->reset();
    // if (m_Options.RawInput)
    //   compResLocal = m_Interp.declare(input);
    // else
    compRes = m_Interp.process(input, result);

    return 0;
  }

  void MetaProcessor::cancelContinuation() const {
    m_InputValidator->reset();
  }

  int MetaProcessor::getExpectedIndent() const {
    return m_InputValidator->getExpectedIndent();
  }

  Interpreter::CompilationResult
  MetaProcessor::readInputFromFile(llvm::StringRef filename,
                                   Value* result,
                                   bool ignoreOutmostBlock /*=false*/) {

    {
      // check that it's not binary:
      std::ifstream in(filename.str().c_str(), std::ios::in | std::ios::binary);
      char magic[1024] = {0};
      in.read(magic, sizeof(magic));
      size_t readMagic = in.gcount();
      if (readMagic >= 4) {
        llvm::StringRef magicStr(magic,in.gcount());
        llvm::sys::fs::file_magic fileType
          = llvm::sys::fs::identify_magic(magicStr);
        if (fileType != llvm::sys::fs::file_magic::unknown) {
          llvm::errs() << "Error in cling::MetaProcessor: "
            "cannot read input from a binary file!\n";
          return Interpreter::kFailure;
        }
        unsigned printable = 0;
        for (size_t i = 0; i < readMagic; ++i)
          if (isprint(magic[i]))
            ++printable;
        if (10 * printable <  5 * readMagic) {
          // 50% printable for ASCII files should be a safe guess.
          llvm::errs() << "Error in cling::MetaProcessor: "
            "cannot read input from a (likely) binary file!\n" << printable;
          return Interpreter::kFailure;
        }
      }
    }

    std::ifstream in(filename.str().c_str());
    in.seekg(0, std::ios::end);
    size_t size = in.tellg();
    std::string content(size, ' ');
    in.seekg(0);
    in.read(&content[0], size);

    if (ignoreOutmostBlock && !content.empty()) {
      static const char whitespace[] = " \t\r\n";
      std::string::size_type posNonWS = content.find_first_not_of(whitespace);
      // Handle comments before leading {
      while (posNonWS != std::string::npos
             && content[posNonWS] == '/' && content[posNonWS+1] == '/') {
        // Remove the comment line
        posNonWS = content.find_first_of('\n', posNonWS+2)+1;
      }
      std::string::size_type replaced = posNonWS;
      if (posNonWS != std::string::npos) {
        if (content[posNonWS] == '{') {
          // hide the curly brace:
          content[posNonWS] = ' ';
          // and the matching closing '}'
          posNonWS = content.find_last_not_of(whitespace);
          if (posNonWS != std::string::npos) {
            if (content[posNonWS] == ';' && content[posNonWS-1] == '}') {
              content[posNonWS--] = ' '; // replace ';' and enter next if
            }
            if (content[posNonWS] == '}') {
              content[posNonWS] = ' '; // replace '}'
            } else {
              std::string::size_type posBlockClose = content.find_last_of('}');
              if (posBlockClose != std::string::npos) {
                content[posBlockClose] = ' '; // replace '}'
              }
              std::string::size_type posComment
                = content.find_first_not_of(whitespace, posComment);
              if (posComment != std::string::npos) {
                if (content[posComment] == '/' && content[posComment+1] == '/') {
                  // More text (comments) are okay after the last '}', but
                  // we can not easily find it to remove it (so we need to upgrade
                  // this code to better handle the case with comments or
                  // preprocessor code before and after the leading { and
                  // trailing })
                  while (posComment <= posNonWS) {
                    content[posComment++] = ' '; // replace '}' and comment
                  }
                } else {
                  content[replaced] = '{';
                  // By putting the '{' back, we keep the code as consistent as
                  // the user wrote it ... but we should still warn that we not
                  // goint to treat this file an unamed macro.
                  llvm::errs()
                  << "Warning in cling::MetaProcessor: can not find the closing '}', "
                  << llvm::sys::path::filename(filename)
                  << " is not handled as an unamed script!\n";
                } // did not find '}''
              } // no whitespace
            } // remove comments after the trailing '}'
          } // find '}'
        } // have '{'
      } // have non-whitespace
    } // ignore outmost block

    std::string strFilename(filename.str());
    m_CurrentlyExecutingFile = strFilename;
    bool topmost = !m_TopExecutingFile.data();
    if (topmost)
      m_TopExecutingFile = m_CurrentlyExecutingFile;
    Interpreter::CompilationResult ret;
    // We don't want to value print the results of a unnamed macro.
    content = "#line 2 \"" + filename.str() + "\" \n" + content;
    if (process((content + ";").c_str(), ret, result)) {
      // Input file has to be complete.
       llvm::errs()
          << "Error in cling::MetaProcessor: file "
          << llvm::sys::path::filename(filename)
          << " is incomplete (missing parenthesis or similar)!\n";
      ret = Interpreter::kFailure;
    }
    m_CurrentlyExecutingFile = llvm::StringRef();
    if (topmost)
      m_TopExecutingFile = llvm::StringRef();
    return ret;
  }

  void MetaProcessor::setFileStream(llvm::StringRef file, bool append, int fd,
              llvm::SmallVector<llvm::SmallString<128>, 2>& prevFileStack) {
    // If we have a fileName to redirect to store it.
    if (!file.empty()) {
      prevFileStack.push_back(file);
      // pop and push a null terminating 0.
      // SmallVectorImpl<T> does not have a c_str(), thus instead of casting to
      // a SmallString<T> we null terminate the data that we have and pop the
      // 0 char back.
      prevFileStack.back().push_back(0);
      prevFileStack.back().pop_back();
      if (!append) {
        FILE * f;
        if (!(f = fopen(file.data(), "w"))) {
          llvm::errs() << "cling::MetaProcessor::setFileStream:"
                       " The file path " << file.data() << "is not valid.";
        } else {
          fclose(f);
        }
      }
    // Else unredirection, so switch to the previous file.
    } else {
      // If there is no previous file on the stack we pop the file
      if (!prevFileStack.empty()) {
        prevFileStack.pop_back();
      }
    }
  }

  void MetaProcessor::setStdStream(llvm::StringRef file,
                                   RedirectionScope stream, bool append) {

    if (stream & kSTDOUT) {
      setFileStream(file, append, STDOUT_FILENO, m_PrevStdoutFileName);
    }
    if (stream & kSTDERR) {
      setFileStream(file, append, STDERR_FILENO, m_PrevStderrFileName);
    }
  }

  int MetaProcessor::copyFileDescriptor(int fd) {
    int backupFD = dup(fd);
    if (backupFD < 0) {
      llvm::errs() << "MetaProcessor::copyFileDescriptor: Duplicating the file"
                   " descriptor " << fd << "resulted in an error."
                   " Will not be able to unredirect.";
    }
    return backupFD;
  }

  void MetaProcessor::registerUnloadPoint(const Transaction* T,
                                          llvm::StringRef filename) {
    m_MetaParser->getActions().registerUnloadPoint(T, filename);
  }

} // end namespace cling
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2013-2014 winlin

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef SRS_CORE_HPP
#define SRS_CORE_HPP

/*
#include <srs_core.hpp>
*/

// current release version
#define VERSION_MAJOR "0"
#define VERSION_MINOR "9"
#define VERSION_REVISION "67"
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
// server info.
#define RTMP_SIG_SRS_KEY "srs"
#define RTMP_SIG_SRS_ROLE "origin server"
#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(simple rtmp server)"
#define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT
#define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server"
#define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin"
#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com"
#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2014 winlin"
#define RTMP_SIG_SRS_PRIMARY_AUTHROS "winlin,wenjie.zhao"
#define RTMP_SIG_SRS_CONTRIBUTORS_URL "https://github.com/winlinvip/simple-rtmp-server/blob/master/AUTHORS.txt"

/**
* the core provides the common defined macros, utilities,
* user must include the srs_core.hpp before any header, or maybe
* build failed.
*/

// for 32bit os, 2G big file limit for unistd io,
// ie. read/write/lseek to use 64bits size for huge file.
#ifndef _FILE_OFFSET_BITS
    #define _FILE_OFFSET_BITS 64
#endif

// for int64_t print using PRId64 format.
#ifndef __STDC_FORMAT_MACROS
    #define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>

#include <assert.h>
#define srs_assert(expression) assert(expression)

#include <stddef.h>
#include <sys/types.h>

// generated by configure.
#include <srs_auto_headers.hpp>

// free the p and set to NULL.
// p must be a T*.
#define srs_freep(p) \
    if (p) { \
        delete p; \
        p = NULL; \
    } \
    (void)0
// free the p which represents a array
#define srs_freepa(p) \
    if (p) { \
        delete[] p; \
        p = NULL; \
    } \
    (void)0

// compare
#define srs_min(a, b) (((a) < (b))? (a) : (b))
#define srs_max(a, b) (((a) < (b))? (b) : (a))

// signal defines.
#define SIGNAL_RELOAD SIGHUP

#include <string>
// replace old_str to new_str of str
extern std::string srs_string_replace(std::string str, std::string old_str, std::string new_str);
// trim char in trim_chars of str
extern std::string srs_string_trim_end(std::string str, std::string trim_chars);
// trim char in trim_chars of str
extern std::string srs_string_trim_start(std::string str, std::string trim_chars);
// remove char in remove_chars of str
extern std::string srs_string_remove(std::string str, std::string remove_chars);
// whether string end with
extern bool srs_string_ends_with(std::string str, std::string flag);

// dns resolve utility, return the resolved ip address.
extern std::string srs_dns_resolve(std::string host);
// whether system is little endian
extern bool srs_is_little_endian();

/**
* disable copy constructor of class
*/
#define disable_default_copy(className)\
    private:\
        /** \
        * disable the copy constructor and operator=, donot allow directly copy. \
        */ \
        className(const className&); \
        className& operator= (const className&)

// const time for st to convert to us
#define SRS_TIME_MILLISECONDS 1000
#define SRS_TIME_SECONDS 1000000

#endif
<commit_msg>change to 0.9.68<commit_after>/*
The MIT License (MIT)

Copyright (c) 2013-2014 winlin

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef SRS_CORE_HPP
#define SRS_CORE_HPP

/*
#include <srs_core.hpp>
*/

// current release version
#define VERSION_MAJOR "0"
#define VERSION_MINOR "9"
#define VERSION_REVISION "68"
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
// server info.
#define RTMP_SIG_SRS_KEY "srs"
#define RTMP_SIG_SRS_ROLE "origin server"
#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(simple rtmp server)"
#define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT
#define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server"
#define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin"
#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com"
#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2014 winlin"
#define RTMP_SIG_SRS_PRIMARY_AUTHROS "winlin,wenjie.zhao"
#define RTMP_SIG_SRS_CONTRIBUTORS_URL "https://github.com/winlinvip/simple-rtmp-server/blob/master/AUTHORS.txt"

/**
* the core provides the common defined macros, utilities,
* user must include the srs_core.hpp before any header, or maybe
* build failed.
*/

// for 32bit os, 2G big file limit for unistd io,
// ie. read/write/lseek to use 64bits size for huge file.
#ifndef _FILE_OFFSET_BITS
    #define _FILE_OFFSET_BITS 64
#endif

// for int64_t print using PRId64 format.
#ifndef __STDC_FORMAT_MACROS
    #define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>

#include <assert.h>
#define srs_assert(expression) assert(expression)

#include <stddef.h>
#include <sys/types.h>

// generated by configure.
#include <srs_auto_headers.hpp>

// free the p and set to NULL.
// p must be a T*.
#define srs_freep(p) \
    if (p) { \
        delete p; \
        p = NULL; \
    } \
    (void)0
// free the p which represents a array
#define srs_freepa(p) \
    if (p) { \
        delete[] p; \
        p = NULL; \
    } \
    (void)0

// compare
#define srs_min(a, b) (((a) < (b))? (a) : (b))
#define srs_max(a, b) (((a) < (b))? (b) : (a))

// signal defines.
#define SIGNAL_RELOAD SIGHUP

#include <string>
// replace old_str to new_str of str
extern std::string srs_string_replace(std::string str, std::string old_str, std::string new_str);
// trim char in trim_chars of str
extern std::string srs_string_trim_end(std::string str, std::string trim_chars);
// trim char in trim_chars of str
extern std::string srs_string_trim_start(std::string str, std::string trim_chars);
// remove char in remove_chars of str
extern std::string srs_string_remove(std::string str, std::string remove_chars);
// whether string end with
extern bool srs_string_ends_with(std::string str, std::string flag);

// dns resolve utility, return the resolved ip address.
extern std::string srs_dns_resolve(std::string host);
// whether system is little endian
extern bool srs_is_little_endian();

/**
* disable copy constructor of class
*/
#define disable_default_copy(className)\
    private:\
        /** \
        * disable the copy constructor and operator=, donot allow directly copy. \
        */ \
        className(const className&); \
        className& operator= (const className&)

// const time for st to convert to us
#define SRS_TIME_MILLISECONDS 1000
#define SRS_TIME_SECONDS 1000000

#endif
<|endoftext|>


<commit_before>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
* License for more details.
*/

#include "ircuser.h"
#include "ircuser_p.h"
#include <qdebug.h>

IRC_BEGIN_NAMESPACE

/*!
    \file ircuser.h
    \brief \#include <IrcUser>
 */

/*!
    \class IrcUser ircuser.h <IrcUser>
    \ingroup models
    \brief Keeps track of user status on a channel.

    \sa IrcUserModel
*/

#ifndef IRC_DOXYGEN
void IrcUserPrivate::setName(const QString& n)
{
    Q_Q(IrcUser);
    if (name != n) {
        name = n;
        emit q->nameChanged(name);
        emit q->titleChanged(q->title());
    }
}

void IrcUserPrivate::setPrefix(const QString& p)
{
    Q_Q(IrcUser);
    if (prefix != p) {
        prefix = p;
        emit q->prefixChanged(prefix);
        emit q->titleChanged(q->title());
    }
}

void IrcUserPrivate::setMode(const QString& m)
{
    Q_Q(IrcUser);
    if (mode != m) {
        mode = m;
        emit q->modeChanged(mode);
    }
}

void IrcUserPrivate::setServOp(const bool& o)
{
    Q_Q(IrcUser);
    if(servOp != o) {
        servOp = o;
        emit q->servOpChanged(servOp);
    }
}

void IrcUserPrivate::setAway(const bool& a)
{
    Q_Q(IrcUser);
    if(away != a) {
        away = a;
        emit q->awayChanged(away);
    }
}
#endif // IRC_DOXYGEN

/*!
    Constructs a new user with \a parent.
 */
IrcUser::IrcUser(QObject* parent)
    : QObject(parent), d_ptr(new IrcUserPrivate)
{
    Q_D(IrcUser);
    d->q_ptr = this;
    d->channel = 0;
    d->away = false;
    d->servOp = false;
}

/*!
    Destructs the user object.
 */
IrcUser::~IrcUser()
{
}

/*!
    This property holds the title.

    The title consists of \ref prefix and \ref name.

    \par Access function:
    \li QString title() const

    \par Notifier signal:
    \li void titleChanged(const QString& title)
 */
QString IrcUser::title() const
{
    Q_D(const IrcUser);
    return d->prefix.left(1) + d->name;
}

/*!
    This property holds the name.

    \par Access function:
    \li QString name() const

    \par Notifier signal:
    \li void nameChanged(const QString& name)
 */
QString IrcUser::name() const
{
    Q_D(const IrcUser);
    return d->name;
}

/*!
    This property holds the prefix character.

    Typical prefix characters are \c @ (op) and \c + (voice).

    \par Access function:
    \li QString prefix() const

    \par Notifier signal:
    \li void prefixChanged(const QString& prefix)
 */
QString IrcUser::prefix() const
{
    Q_D(const IrcUser);
    return d->prefix;
}

/*!
    This property holds the mode letter.

    Typical mode letters are \c o (op) and \c v (voice).

    \par Access function:
    \li QString mode() const

    \par Notifier signal:
    \li void modeChanged(const QString& mode)
 */
QString IrcUser::mode() const
{
    Q_D(const IrcUser);
    return d->mode;
}

bool IrcUser::isServOp() const
{
    Q_D(const IrcUser);
    return d->servOp;
}

bool IrcUser::isAway() const
{
    Q_D(const IrcUser);
    return d->away;
}

/*!
    This property holds the channel of the user.

    \par Access function:
    \li \ref IrcChannel* channel() const
 */
IrcChannel* IrcUser::channel() const
{
    Q_D(const IrcUser);
    return d->channel;
}

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const IrcUser* user)
{
    if (!user)
        return debug << "IrcUser(0x0) ";
    debug.nospace() << user->metaObject()->className() << '(' << (void*) user;
    if (!user->objectName().isEmpty())
        debug.nospace() << ", name=" << qPrintable(user->objectName());
    if (!user->name().isEmpty())
        debug.nospace() << ", user=" << qPrintable(user->name());
    debug.nospace() << ')';
    return debug.space();
}
#endif // QT_NO_DEBUG_STREAM

#include "moc_ircuser.cpp"

IRC_END_NAMESPACE
<commit_msg>IrcUser: fix coding style :)<commit_after>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
* License for more details.
*/

#include "ircuser.h"
#include "ircuser_p.h"
#include <qdebug.h>

IRC_BEGIN_NAMESPACE

/*!
    \file ircuser.h
    \brief \#include <IrcUser>
 */

/*!
    \class IrcUser ircuser.h <IrcUser>
    \ingroup models
    \brief Keeps track of user status on a channel.

    \sa IrcUserModel
*/

#ifndef IRC_DOXYGEN
void IrcUserPrivate::setName(const QString& n)
{
    Q_Q(IrcUser);
    if (name != n) {
        name = n;
        emit q->nameChanged(name);
        emit q->titleChanged(q->title());
    }
}

void IrcUserPrivate::setPrefix(const QString& p)
{
    Q_Q(IrcUser);
    if (prefix != p) {
        prefix = p;
        emit q->prefixChanged(prefix);
        emit q->titleChanged(q->title());
    }
}

void IrcUserPrivate::setMode(const QString& m)
{
    Q_Q(IrcUser);
    if (mode != m) {
        mode = m;
        emit q->modeChanged(mode);
    }
}

void IrcUserPrivate::setServOp(const bool& o)
{
    Q_Q(IrcUser);
    if (servOp != o) {
        servOp = o;
        emit q->servOpChanged(servOp);
    }
}

void IrcUserPrivate::setAway(const bool& a)
{
    Q_Q(IrcUser);
    if (away != a) {
        away = a;
        emit q->awayChanged(away);
    }
}
#endif // IRC_DOXYGEN

/*!
    Constructs a new user with \a parent.
 */
IrcUser::IrcUser(QObject* parent)
    : QObject(parent), d_ptr(new IrcUserPrivate)
{
    Q_D(IrcUser);
    d->q_ptr = this;
    d->channel = 0;
    d->away = false;
    d->servOp = false;
}

/*!
    Destructs the user object.
 */
IrcUser::~IrcUser()
{
}

/*!
    This property holds the title.

    The title consists of \ref prefix and \ref name.

    \par Access function:
    \li QString title() const

    \par Notifier signal:
    \li void titleChanged(const QString& title)
 */
QString IrcUser::title() const
{
    Q_D(const IrcUser);
    return d->prefix.left(1) + d->name;
}

/*!
    This property holds the name.

    \par Access function:
    \li QString name() const

    \par Notifier signal:
    \li void nameChanged(const QString& name)
 */
QString IrcUser::name() const
{
    Q_D(const IrcUser);
    return d->name;
}

/*!
    This property holds the prefix character.

    Typical prefix characters are \c @ (op) and \c + (voice).

    \par Access function:
    \li QString prefix() const

    \par Notifier signal:
    \li void prefixChanged(const QString& prefix)
 */
QString IrcUser::prefix() const
{
    Q_D(const IrcUser);
    return d->prefix;
}

/*!
    This property holds the mode letter.

    Typical mode letters are \c o (op) and \c v (voice).

    \par Access function:
    \li QString mode() const

    \par Notifier signal:
    \li void modeChanged(const QString& mode)
 */
QString IrcUser::mode() const
{
    Q_D(const IrcUser);
    return d->mode;
}

bool IrcUser::isServOp() const
{
    Q_D(const IrcUser);
    return d->servOp;
}

bool IrcUser::isAway() const
{
    Q_D(const IrcUser);
    return d->away;
}

/*!
    This property holds the channel of the user.

    \par Access function:
    \li \ref IrcChannel* channel() const
 */
IrcChannel* IrcUser::channel() const
{
    Q_D(const IrcUser);
    return d->channel;
}

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const IrcUser* user)
{
    if (!user)
        return debug << "IrcUser(0x0) ";
    debug.nospace() << user->metaObject()->className() << '(' << (void*) user;
    if (!user->objectName().isEmpty())
        debug.nospace() << ", name=" << qPrintable(user->objectName());
    if (!user->name().isEmpty())
        debug.nospace() << ", user=" << qPrintable(user->name());
    debug.nospace() << ')';
    return debug.space();
}
#endif // QT_NO_DEBUG_STREAM

#include "moc_ircuser.cpp"

IRC_END_NAMESPACE
<|endoftext|>


<commit_before>#include "highlighters.hh"

#include "assert.hh"
#include "window.hh"
#include "display_buffer.hh"
#include "highlighter_registry.hh"
#include "highlighter_group.hh"
#include <boost/regex.hpp>

namespace Kakoune
{

void colorize_regex_range(DisplayBuffer& display_buffer,
                          const BufferIterator& range_begin,
                          const BufferIterator& range_end,
                          const boost::regex& ex,
                          Color fg_color, Color bg_color = Color::Default)
{
    assert(range_begin <= range_end);

    if (range_begin >= display_buffer.back().end() or
        range_end <= display_buffer.front().begin())
        return;

    BufferIterator display_begin = std::max(range_begin,
                                            display_buffer.front().begin());
    BufferIterator display_end   = std::min(range_end,
                                            display_buffer.back().end());

    boost::regex_iterator<BufferIterator> re_it(display_begin, display_end,
                                                ex, boost::match_nosubs);
    boost::regex_iterator<BufferIterator> re_end;
    DisplayBuffer::iterator atom_it = display_buffer.begin();
    for (; re_it != re_end; ++re_it)
    {
        BufferIterator begin = (*re_it)[0].first;
        BufferIterator end   = (*re_it)[0].second;
        assert(begin != end);

        auto begin_atom_it = display_buffer.atom_containing(begin, atom_it);
        assert(begin_atom_it != display_buffer.end());
        if (begin_atom_it->begin() != begin)
            begin_atom_it = ++display_buffer.split(begin_atom_it, begin);

        auto end_atom_it = display_buffer.atom_containing(end, begin_atom_it);
        if (end_atom_it != display_buffer.end() and
            end_atom_it->begin() != end)
            end_atom_it = ++display_buffer.split(end_atom_it, end);

        assert(begin_atom_it != end_atom_it);

        for (auto it = begin_atom_it; it != end_atom_it; ++it)
        {
            it->fg_color() = fg_color;
            it->bg_color() = bg_color;
        }

        atom_it = end_atom_it;
    }
}

void colorize_regex(DisplayBuffer& display_buffer,
                    const boost::regex& ex,
                    Color fg_color, Color bg_color = Color::Default)
{
    colorize_regex_range(display_buffer, display_buffer.front().begin(),
                         display_buffer.back().end(), ex, fg_color, bg_color);
}

Color parse_color(const std::string& color)
{
    if (color == "default") return Color::Default;
    if (color == "black")   return Color::Black;
    if (color == "red")     return Color::Red;
    if (color == "green")   return Color::Green;
    if (color == "yellow")  return Color::Yellow;
    if (color == "blue")    return Color::Blue;
    if (color == "magenta") return Color::Magenta;
    if (color == "cyan")    return Color::Cyan;
    if (color == "white")   return Color::White;
    return Color::Default;
}

HighlighterAndId colorize_regex_factory(Window& window,
                                        const HighlighterParameters params)
{
    if (params.size() != 3)
        throw runtime_error("wrong parameter count");

    boost::regex ex(params[0]);

    Color fg_color = parse_color(params[1]);
    Color bg_color = parse_color(params[2]);

    std::string id = "colre'" + params[0] + "'";

    return HighlighterAndId(id, std::bind(colorize_regex, std::placeholders::_1,
                                     ex, fg_color, bg_color));
}

void expand_tabulations(DisplayBuffer& display_buffer)
{
    const int tabstop = 8;
    for (auto atom_it = display_buffer.begin();
         atom_it != display_buffer.end(); ++atom_it)
    {
        for (BufferIterator it = atom_it->begin(); it != atom_it->end(); ++it)
        {
            if (*it == '\t')
            {
                if (it != atom_it->begin())
                    atom_it = ++display_buffer.split(atom_it, it);

                if (it+1 != atom_it->end())
                    atom_it = display_buffer.split(atom_it, it+1);

                BufferCoord pos = it.buffer().line_and_column_at(it);

                int column = 0;
                for (auto line_it = it.buffer().iterator_at({pos.line, 0});
                     line_it != it; ++line_it)
                {
                    assert(*line_it != '\n');
                    if (*line_it == '\t')
                        column += tabstop - (column % tabstop);
                    else
                       ++column;
                }

                int count = tabstop - (column % tabstop);
                display_buffer.replace_atom_content(atom_it,
                                                    std::string(count, ' '));
            }
        }
    }
}

void show_line_numbers(DisplayBuffer& display_buffer)
{
    const Buffer& buffer = display_buffer.front().begin().buffer();
    BufferCoord coord = buffer.line_and_column_at(display_buffer.begin()->begin());

    int last_line = buffer.line_and_column_at(display_buffer.back().end()-1).line;

    for (; coord.line <= last_line; ++coord.line)
    {
        BufferIterator line_start = buffer.iterator_at(coord);
        DisplayBuffer::iterator atom_it = display_buffer.atom_containing(line_start);
        if (atom_it != display_buffer.end())
        {
            if (atom_it->begin() != line_start)
            {
                if (not atom_it->splitable())
                    continue;

                atom_it = ++display_buffer.split(atom_it, line_start);
            }
            atom_it = display_buffer.insert(
                atom_it,
                DisplayAtom(atom_it->coord(),
                            atom_it->begin(), atom_it->begin(),
                            Color::Black, Color::White));

            char buffer[6];
            snprintf(buffer, 6, "%3d ", coord.line + 1);
            display_buffer.replace_atom_content(atom_it, buffer);
        }
    }
}

template<void (*highlighter_func)(DisplayBuffer&)>
class SimpleHighlighterFactory
{
public:
    SimpleHighlighterFactory(const std::string& id) : m_id(id) {}

    HighlighterAndId operator()(Window& window,
                                const HighlighterParameters& params) const
    {
        return HighlighterAndId(m_id, HighlighterFunc(highlighter_func));
    }
private:
    std::string m_id;
};

class SelectionsHighlighter
{
public:
    SelectionsHighlighter(Window& window)
        : m_window(window)
    {
    }

    void operator()(DisplayBuffer& display_buffer)
    {
        SelectionList sorted_selections = m_window.selections();

        std::sort(sorted_selections.begin(), sorted_selections.end(),
                  [](const Selection& lhs, const Selection& rhs) { return lhs.begin() < rhs.begin(); });

        auto atom_it = display_buffer.begin();
        auto sel_it = sorted_selections.begin();

        while (atom_it != display_buffer.end()
               and sel_it != sorted_selections.end())
        {
            Selection& sel = *sel_it;
            DisplayAtom& atom = *atom_it;

            // [###------]
            if (atom.begin() >= sel.begin() and atom.begin() < sel.end() and atom.end() > sel.end())
            {
                atom_it = display_buffer.split(atom_it, sel.end());
                atom_it->attribute() |= Attributes::Underline;
                ++atom_it;
                ++sel_it;
            }
            // [---###---]
            else if (atom.begin() < sel.begin() and atom.end() > sel.end())
            {
                atom_it = display_buffer.split(atom_it, sel.begin());
                atom_it = display_buffer.split(++atom_it, sel.end());
                atom_it->attribute() |= Attributes::Underline;
                ++atom_it;
                ++sel_it;
            }
            // [------###]
            else if (atom.begin() < sel.begin() and atom.end() > sel.begin())
            {
                atom_it = ++display_buffer.split(atom_it, sel.begin());
                atom_it->attribute() |= Attributes::Underline;
                ++atom_it;
            }
            // [#########]
            else if (atom.begin() >= sel.begin() and atom.end() <= sel.end())
            {
                atom_it->attribute() |= Attributes::Underline;
                ++atom_it;
            }
            // [---------]
            else if (atom.begin() >= sel.end())
                ++sel_it;
            // [---------]
            else if (atom.end() <= sel.begin())
                ++atom_it;
            else
                assert(false);
        }

        boost::regex ex("\n");
        for (auto& sel : sorted_selections)
             colorize_regex_range(display_buffer, sel.begin(), sel.end(),
                                  ex, Color::Default, Color::Yellow);

    }

    static HighlighterAndId create(Window& window,
                                   const HighlighterParameters& params)
    {
        return HighlighterAndId("highlight_selections",
                            SelectionsHighlighter(window));
    }

private:
    const Window& m_window;
};

HighlighterAndId highlighter_group_factory(Window& window,
                                           const HighlighterParameters& params)
{
    if (params.size() != 1)
        throw runtime_error("wrong parameter count");

    return HighlighterAndId(params[0], HighlighterGroup());
}

void register_highlighters()
{
    HighlighterRegistry& registry = HighlighterRegistry::instance();

    registry.register_factory("highlight_selections", SelectionsHighlighter::create);
    registry.register_factory("expand_tabs", SimpleHighlighterFactory<expand_tabulations>("expand_tabs"));
    registry.register_factory("number_lines", SimpleHighlighterFactory<show_line_numbers>("number_lines"));
    registry.register_factory("regex", colorize_regex_factory);
    registry.register_factory("group", highlighter_group_factory);
}

}
<commit_msg>optimize SelectionHighlighters, stop copying Selections<commit_after>#include "highlighters.hh"

#include "assert.hh"
#include "window.hh"
#include "display_buffer.hh"
#include "highlighter_registry.hh"
#include "highlighter_group.hh"
#include <boost/regex.hpp>

namespace Kakoune
{

void colorize_regex_range(DisplayBuffer& display_buffer,
                          const BufferIterator& range_begin,
                          const BufferIterator& range_end,
                          const boost::regex& ex,
                          Color fg_color, Color bg_color = Color::Default)
{
    assert(range_begin <= range_end);

    if (range_begin >= display_buffer.back().end() or
        range_end <= display_buffer.front().begin())
        return;

    BufferIterator display_begin = std::max(range_begin,
                                            display_buffer.front().begin());
    BufferIterator display_end   = std::min(range_end,
                                            display_buffer.back().end());

    boost::regex_iterator<BufferIterator> re_it(display_begin, display_end,
                                                ex, boost::match_nosubs);
    boost::regex_iterator<BufferIterator> re_end;
    DisplayBuffer::iterator atom_it = display_buffer.begin();
    for (; re_it != re_end; ++re_it)
    {
        BufferIterator begin = (*re_it)[0].first;
        BufferIterator end   = (*re_it)[0].second;
        assert(begin != end);

        auto begin_atom_it = display_buffer.atom_containing(begin, atom_it);
        assert(begin_atom_it != display_buffer.end());
        if (begin_atom_it->begin() != begin)
            begin_atom_it = ++display_buffer.split(begin_atom_it, begin);

        auto end_atom_it = display_buffer.atom_containing(end, begin_atom_it);
        if (end_atom_it != display_buffer.end() and
            end_atom_it->begin() != end)
            end_atom_it = ++display_buffer.split(end_atom_it, end);

        assert(begin_atom_it != end_atom_it);

        for (auto it = begin_atom_it; it != end_atom_it; ++it)
        {
            it->fg_color() = fg_color;
            it->bg_color() = bg_color;
        }

        atom_it = end_atom_it;
    }
}

void colorize_regex(DisplayBuffer& display_buffer,
                    const boost::regex& ex,
                    Color fg_color, Color bg_color = Color::Default)
{
    colorize_regex_range(display_buffer, display_buffer.front().begin(),
                         display_buffer.back().end(), ex, fg_color, bg_color);
}

Color parse_color(const std::string& color)
{
    if (color == "default") return Color::Default;
    if (color == "black")   return Color::Black;
    if (color == "red")     return Color::Red;
    if (color == "green")   return Color::Green;
    if (color == "yellow")  return Color::Yellow;
    if (color == "blue")    return Color::Blue;
    if (color == "magenta") return Color::Magenta;
    if (color == "cyan")    return Color::Cyan;
    if (color == "white")   return Color::White;
    return Color::Default;
}

HighlighterAndId colorize_regex_factory(Window& window,
                                        const HighlighterParameters params)
{
    if (params.size() != 3)
        throw runtime_error("wrong parameter count");

    boost::regex ex(params[0]);

    Color fg_color = parse_color(params[1]);
    Color bg_color = parse_color(params[2]);

    std::string id = "colre'" + params[0] + "'";

    return HighlighterAndId(id, std::bind(colorize_regex, std::placeholders::_1,
                                     ex, fg_color, bg_color));
}

void expand_tabulations(DisplayBuffer& display_buffer)
{
    const int tabstop = 8;
    for (auto atom_it = display_buffer.begin();
         atom_it != display_buffer.end(); ++atom_it)
    {
        for (BufferIterator it = atom_it->begin(); it != atom_it->end(); ++it)
        {
            if (*it == '\t')
            {
                if (it != atom_it->begin())
                    atom_it = ++display_buffer.split(atom_it, it);

                if (it+1 != atom_it->end())
                    atom_it = display_buffer.split(atom_it, it+1);

                BufferCoord pos = it.buffer().line_and_column_at(it);

                int column = 0;
                for (auto line_it = it.buffer().iterator_at({pos.line, 0});
                     line_it != it; ++line_it)
                {
                    assert(*line_it != '\n');
                    if (*line_it == '\t')
                        column += tabstop - (column % tabstop);
                    else
                       ++column;
                }

                int count = tabstop - (column % tabstop);
                display_buffer.replace_atom_content(atom_it,
                                                    std::string(count, ' '));
            }
        }
    }
}

void show_line_numbers(DisplayBuffer& display_buffer)
{
    const Buffer& buffer = display_buffer.front().begin().buffer();
    BufferCoord coord = buffer.line_and_column_at(display_buffer.begin()->begin());

    int last_line = buffer.line_and_column_at(display_buffer.back().end()-1).line;

    for (; coord.line <= last_line; ++coord.line)
    {
        BufferIterator line_start = buffer.iterator_at(coord);
        DisplayBuffer::iterator atom_it = display_buffer.atom_containing(line_start);
        if (atom_it != display_buffer.end())
        {
            if (atom_it->begin() != line_start)
            {
                if (not atom_it->splitable())
                    continue;

                atom_it = ++display_buffer.split(atom_it, line_start);
            }
            atom_it = display_buffer.insert(
                atom_it,
                DisplayAtom(atom_it->coord(),
                            atom_it->begin(), atom_it->begin(),
                            Color::Black, Color::White));

            char buffer[6];
            snprintf(buffer, 6, "%3d ", coord.line + 1);
            display_buffer.replace_atom_content(atom_it, buffer);
        }
    }
}

template<void (*highlighter_func)(DisplayBuffer&)>
class SimpleHighlighterFactory
{
public:
    SimpleHighlighterFactory(const std::string& id) : m_id(id) {}

    HighlighterAndId operator()(Window& window,
                                const HighlighterParameters& params) const
    {
        return HighlighterAndId(m_id, HighlighterFunc(highlighter_func));
    }
private:
    std::string m_id;
};

class SelectionsHighlighter
{
public:
    SelectionsHighlighter(Window& window)
        : m_window(window)
    {
    }

    void operator()(DisplayBuffer& display_buffer)
    {
        typedef std::pair<BufferIterator, BufferIterator> BufferRange;

        std::vector<BufferRange> selections;
        for (auto& sel : m_window.selections())
            selections.push_back(BufferRange(sel.begin(), sel.end()));

        std::sort(selections.begin(), selections.end(),
                  [](const BufferRange& lhs, const BufferRange& rhs)
                  { return lhs.first < rhs.first; });

        auto atom_it = display_buffer.begin();
        auto sel_it = selections.begin();

        while (atom_it != display_buffer.end()
               and sel_it != selections.end())
        {
            BufferRange& sel = *sel_it;
            DisplayAtom& atom = *atom_it;

            // [###------]
            if (atom.begin() >= sel.first and atom.begin() < sel.second and
                atom.end() > sel.second)
            {
                atom_it = display_buffer.split(atom_it, sel.second);
                atom_it->attribute() |= Attributes::Underline;
                ++atom_it;
                ++sel_it;
            }
            // [---###---]
            else if (atom.begin() < sel.first and atom.end() > sel.second)
            {
                atom_it = display_buffer.split(atom_it, sel.first);
                atom_it = display_buffer.split(++atom_it, sel.second);
                atom_it->attribute() |= Attributes::Underline;
                ++atom_it;
                ++sel_it;
            }
            // [------###]
            else if (atom.begin() < sel.first and atom.end() > sel.first)
            {
                atom_it = ++display_buffer.split(atom_it, sel.first);
                atom_it->attribute() |= Attributes::Underline;
                ++atom_it;
            }
            // [#########]
            else if (atom.begin() >= sel.first and atom.end() <= sel.second)
            {
                atom_it->attribute() |= Attributes::Underline;
                ++atom_it;
            }
            // [---------]
            else if (atom.begin() >= sel.second)
                ++sel_it;
            // [---------]
            else if (atom.end() <= sel.first)
                ++atom_it;
            else
                assert(false);
        }

        boost::regex ex("\n");
        for (auto& sel : selections)
             colorize_regex_range(display_buffer, sel.first, sel.second,
                                  ex, Color::Default, Color::Yellow);

    }

    static HighlighterAndId create(Window& window,
                                   const HighlighterParameters& params)
    {
        return HighlighterAndId("highlight_selections",
                            SelectionsHighlighter(window));
    }

private:
    const Window& m_window;
};

HighlighterAndId highlighter_group_factory(Window& window,
                                           const HighlighterParameters& params)
{
    if (params.size() != 1)
        throw runtime_error("wrong parameter count");

    return HighlighterAndId(params[0], HighlighterGroup());
}

void register_highlighters()
{
    HighlighterRegistry& registry = HighlighterRegistry::instance();

    registry.register_factory("highlight_selections", SelectionsHighlighter::create);
    registry.register_factory("expand_tabs", SimpleHighlighterFactory<expand_tabulations>("expand_tabs"));
    registry.register_factory("number_lines", SimpleHighlighterFactory<show_line_numbers>("number_lines"));
    registry.register_factory("regex", colorize_regex_factory);
    registry.register_factory("group", highlighter_group_factory);
}

}
<|endoftext|>


<commit_before>/// \file
/// \ingroup tutorial_spectrum
/// \notebook
/// Example to illustrate the 2-d peak finder (class TSpectrum2).
///
/// This script generates a random number of 2-d gaussian peaks
/// The position of the peaks is found via TSpectrum2
/// To execute this example, do:
///
/// ~~~{.cpp}
///  root > .x peaks2.C  (generate up to 50 peaks by default)
///  root > .x peaks2.C(10) (generate up to 10 peaks)
///  root > .x peaks2.C+(200) (generate up to 200 peaks via ACLIC)
/// ~~~
///
/// The script will iterate generating a new histogram having
/// between 5 and the maximun number of peaks specified.
/// Double Click on the bottom right corner of the pad to go to a new spectrum
/// To Quit, select the "quit" item in the canvas "File" menu
///
/// \macro_image
/// \macro_code
///
/// \author Rene Brun

#include "TSpectrum2.h"
#include "TCanvas.h"
#include "TRandom.h"
#include "TH2.h"
#include "TF2.h"
#include "TMath.h"
#include "TROOT.h"

TSpectrum2 *s;
TH2F *h2 = 0;
Int_t npeaks = 30;
Double_t fpeaks2(Double_t *x, Double_t *par) {
   Double_t result = 0.1;
   for (Int_t p=0;p<npeaks;p++) {
      Double_t norm   = par[5*p+0];
      Double_t mean1  = par[5*p+1];
      Double_t sigma1 = par[5*p+2];
      Double_t mean2  = par[5*p+3];
      Double_t sigma2 = par[5*p+4];
      result += norm*TMath::Gaus(x[0],mean1,sigma1)*TMath::Gaus(x[1],mean2,sigma2);
   }
   return result;
}
void findPeak2() {
   printf("Generating histogram with %d peaks\n",npeaks);
   Int_t nbinsx = 200;
   Int_t nbinsy = 200;
   Double_t xmin   = 0;
   Double_t xmax   = (Double_t)nbinsx;
   Double_t ymin   = 0;
   Double_t ymax   = (Double_t)nbinsy;
   Double_t dx = (xmax-xmin)/nbinsx;
   Double_t dy = (ymax-ymin)/nbinsy;
   delete h2;
   h2 = new TH2F("h2","test",nbinsx,xmin,xmax,nbinsy,ymin,ymax);
   h2->SetStats(0);
   //generate n peaks at random
   Double_t par[3000];
   Int_t p;
   for (p=0;p<npeaks;p++) {
      par[5*p+0] = gRandom->Uniform(0.2,1);
      par[5*p+1] = gRandom->Uniform(xmin,xmax);
      par[5*p+2] = gRandom->Uniform(dx,5*dx);
      par[5*p+3] = gRandom->Uniform(ymin,ymax);
      par[5*p+4] = gRandom->Uniform(dy,5*dy);
   }
   TF2 *f2 = new TF2("f2",fpeaks2,xmin,xmax,ymin,ymax,5*npeaks);
   f2->SetNpx(100);
   f2->SetNpy(100);
   f2->SetParameters(par);
   TCanvas *c1 = (TCanvas*)gROOT->GetListOfCanvases()->FindObject("c1");
   if (!c1) c1 = new TCanvas("c1","c1",10,10,1000,700);
   h2->FillRandom("f2",500000);

   //now the real stuff: Finding the peaks
   Int_t nfound = s->Search(h2,2,"col");

   //searching good and ghost peaks (approximation)
   Int_t pf,ngood = 0;
   Double_t *xpeaks = s->GetPositionX();
   Double_t *ypeaks = s->GetPositionY();
   for (p=0;p<npeaks;p++) {
      for (pf=0;pf<nfound;pf++) {
         Double_t diffx = TMath::Abs(xpeaks[pf] - par[5*p+1]);
         Double_t diffy = TMath::Abs(ypeaks[pf] - par[5*p+3]);
         if (diffx < 2*dx && diffy < 2*dy) ngood++;
      }
   }
   if (ngood > nfound) ngood = nfound;
   //Search ghost peaks (approximation)
   Int_t nghost = 0;
   for (pf=0;pf<nfound;pf++) {
      Int_t nf=0;
      for (p=0;p<npeaks;p++) {
         Double_t diffx = TMath::Abs(xpeaks[pf] - par[5*p+1]);
         Double_t diffy = TMath::Abs(ypeaks[pf] - par[5*p+3]);
         if (diffx < 2*dx && diffy < 2*dy) nf++;
      }
      if (nf == 0) nghost++;
   }
   c1->Update();

   s->Print();
   printf("Gener=%d, Found=%d, Good=%d, Ghost=%d\n",npeaks,nfound,ngood,nghost);
   printf("\nDouble click in the bottom right corner of the pad to continue\n");
   c1->WaitPrimitive();
}
void peaks2(Int_t maxpeaks=50) {
   s = new TSpectrum2(2*maxpeaks);
   for (int i=0; i<10; ++i) {
      npeaks = (Int_t)gRandom->Uniform(5,maxpeaks);
      findPeak2();
   }
}

<commit_msg>Don't wait for user interaction in batch mode<commit_after>/// \file
/// \ingroup tutorial_spectrum
/// \notebook
/// Example to illustrate the 2-d peak finder (class TSpectrum2).
///
/// This script generates a random number of 2-d gaussian peaks
/// The position of the peaks is found via TSpectrum2
/// To execute this example, do:
///
/// ~~~{.cpp}
///  root > .x peaks2.C  (generate up to 50 peaks by default)
///  root > .x peaks2.C(10) (generate up to 10 peaks)
///  root > .x peaks2.C+(200) (generate up to 200 peaks via ACLIC)
/// ~~~
///
/// The script will iterate generating a new histogram having
/// between 5 and the maximun number of peaks specified.
/// Double Click on the bottom right corner of the pad to go to a new spectrum
/// To Quit, select the "quit" item in the canvas "File" menu
///
/// \macro_image
/// \macro_code
///
/// \author Rene Brun

#include "TSpectrum2.h"
#include "TCanvas.h"
#include "TRandom.h"
#include "TH2.h"
#include "TF2.h"
#include "TMath.h"
#include "TROOT.h"

TSpectrum2 *s;
TH2F *h2 = 0;
Int_t npeaks = 30;
Double_t fpeaks2(Double_t *x, Double_t *par) {
   Double_t result = 0.1;
   for (Int_t p=0;p<npeaks;p++) {
      Double_t norm   = par[5*p+0];
      Double_t mean1  = par[5*p+1];
      Double_t sigma1 = par[5*p+2];
      Double_t mean2  = par[5*p+3];
      Double_t sigma2 = par[5*p+4];
      result += norm*TMath::Gaus(x[0],mean1,sigma1)*TMath::Gaus(x[1],mean2,sigma2);
   }
   return result;
}
void findPeak2() {
   printf("Generating histogram with %d peaks\n",npeaks);
   Int_t nbinsx = 200;
   Int_t nbinsy = 200;
   Double_t xmin   = 0;
   Double_t xmax   = (Double_t)nbinsx;
   Double_t ymin   = 0;
   Double_t ymax   = (Double_t)nbinsy;
   Double_t dx = (xmax-xmin)/nbinsx;
   Double_t dy = (ymax-ymin)/nbinsy;
   delete h2;
   h2 = new TH2F("h2","test",nbinsx,xmin,xmax,nbinsy,ymin,ymax);
   h2->SetStats(0);
   //generate n peaks at random
   Double_t par[3000];
   Int_t p;
   for (p=0;p<npeaks;p++) {
      par[5*p+0] = gRandom->Uniform(0.2,1);
      par[5*p+1] = gRandom->Uniform(xmin,xmax);
      par[5*p+2] = gRandom->Uniform(dx,5*dx);
      par[5*p+3] = gRandom->Uniform(ymin,ymax);
      par[5*p+4] = gRandom->Uniform(dy,5*dy);
   }
   TF2 *f2 = new TF2("f2",fpeaks2,xmin,xmax,ymin,ymax,5*npeaks);
   f2->SetNpx(100);
   f2->SetNpy(100);
   f2->SetParameters(par);
   TCanvas *c1 = (TCanvas*)gROOT->GetListOfCanvases()->FindObject("c1");
   if (!c1) c1 = new TCanvas("c1","c1",10,10,1000,700);
   h2->FillRandom("f2",500000);

   //now the real stuff: Finding the peaks
   Int_t nfound = s->Search(h2,2,"col");

   //searching good and ghost peaks (approximation)
   Int_t pf,ngood = 0;
   Double_t *xpeaks = s->GetPositionX();
   Double_t *ypeaks = s->GetPositionY();
   for (p=0;p<npeaks;p++) {
      for (pf=0;pf<nfound;pf++) {
         Double_t diffx = TMath::Abs(xpeaks[pf] - par[5*p+1]);
         Double_t diffy = TMath::Abs(ypeaks[pf] - par[5*p+3]);
         if (diffx < 2*dx && diffy < 2*dy) ngood++;
      }
   }
   if (ngood > nfound) ngood = nfound;
   //Search ghost peaks (approximation)
   Int_t nghost = 0;
   for (pf=0;pf<nfound;pf++) {
      Int_t nf=0;
      for (p=0;p<npeaks;p++) {
         Double_t diffx = TMath::Abs(xpeaks[pf] - par[5*p+1]);
         Double_t diffy = TMath::Abs(ypeaks[pf] - par[5*p+3]);
         if (diffx < 2*dx && diffy < 2*dy) nf++;
      }
      if (nf == 0) nghost++;
   }
   c1->Update();

   s->Print();
   printf("Gener=%d, Found=%d, Good=%d, Ghost=%d\n",npeaks,nfound,ngood,nghost);
   if (!gROOT->IsBatch()) {
      printf("\nDouble click in the bottom right corner of the pad to continue\n");
      c1->WaitPrimitive();
   }
}
void peaks2(Int_t maxpeaks=50) {
   s = new TSpectrum2(2*maxpeaks);
   for (int i=0; i<10; ++i) {
      npeaks = (Int_t)gRandom->Uniform(5,maxpeaks);
      findPeak2();
   }
}

<|endoftext|>