<commit_before>/*
 * File:   calc_estatics.cpp
 * Author: mayfalk
 *
 * Created on May 21, 2010, 11:21 PM
 */

#include <stdlib.h>
#include "estatics.h"
#include <math.h>
#include <list>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <fstream>

void CalcEstatics::Initialize(QMTopology *top, Property *options) {
    _options = options;
    if (options->exists("options.estatic_params.epsilon_dielectric")) {
        _epsilon_dielectric = options->get("options.estatic_params.epsilon_dielectric").as<double>();
    } else {
        _epsilon_dielectric = 3.0;
        cout << "Warning: dielectric constant in not provided, using default" << endl;
    }

    if (options->exists("options.estatic_params.s_eps")) {
        _s_eps = options->get("options.estatic_params.s_eps").as<double>();
    } else {
        _s_eps = 3.0;
        cout << "Warning: s_eps is not provided, using default" << endl;
    }

    if (options->exists("options.estatic_params.estatic_method")) {
        if (options->get("options.estatic_params.estatic_method").as<string > () == "distdep") {
            _estatic_method = &CalcEstatics::dist_dep_eps;
            cout << "Doing distance-dependent-eps estatic with eps " << _epsilon_dielectric << " and s_eps " << _s_eps << endl;
        }
        if (options->get("options.estatic_params.estatic_method").as<string > () == "simple") {
            _estatic_method = &CalcEstatics::constant_epsilon;
            cout << "Doing simple estatic with eps " << _epsilon_dielectric << endl;
        } else if (options->get("options.estatic_params.estatic_method").as<string > () == "dipoles") {
            _estatic_method = &CalcEstatics::constant_epsilon;
            cout << "Doing interactions including dipoles with eps =1 " << endl;
        } else throw std::runtime_error("Error in CalcEstatics::Initialize : no such estatic method, should be simple or distdep");
    } else throw std::runtime_error("Error in CalcEstatics:Initialize : no estatic_method specified");
}

bool CalcEstatics::EvaluateFrame(QMTopology *top) {
    vector<CrgUnit *> lcharges = top->CrgUnits();
    Topology atop;
    atop.setBox(top->getBox());
    for (vector<CrgUnit *>::iterator itl = lcharges.begin(); itl != lcharges.end(); itl++) {
        top->AddAtomisticBeads(*itl, &atop);
    }
    cout << "Number of charge units in top " << lcharges.size() << endl;
    cout << "Number of molecules in atop " << atop.MoleculeCount() << endl;
    double crged, neutr;

    MoleculeContainer::iterator imol;
    for (imol = atop.Molecules().begin(); imol != atop.Molecules().end(); imol++) {
        Molecule *mol = *imol;
        CrgUnit *crg = mol->getUserData<CrgUnit > ();
        //if induced dipoles then directly go to charged system
        if (_options->get("options.estatic_params.estatic_method").as<string > () == "dipoles") {

            //Change the charges on the molecule mol to the occupied=charged state
            top->CopyChargesOccupied(crg, mol);
            //read in the induced dipole moments
            string s;
            int nr = mol->getId();
            string filename = "d_" + boost::lexical_cast<string > (nr);
            ifstream indata;
            indata.open(filename.c_str());
            for (BeadContainer::iterator iter = atop.Beads().begin();
                    iter != atop.Beads().end(); ++iter) { // keep reading until end-of-file
                Bead *b = *iter;
                getline(indata, s);
                Tokenizer tok(s, " ");
                vector<double> v;
                tok.ConvertToVector(v);
                if (v.size() != 3)
                    throw std::ios_base::failure("invalid dipole format. should be dx dy dz in Debeye separated by one space");
                double vx = v[0];
                double vy = v[1];
                double vz = v[2];
                b->setUserData<vec > (new vec(vx, vy, vz));
            }
            indata.close();
            crged = CalcPot_Dipole(&atop, mol);
            neutr = 0.0;
            top->CopyCharges(crg, mol);
        }
            //otherwise do the regular estatics shit
        else {
            //Compute the EstaticPotentialEnergy for molecule mol if it is neutral
            neutr = CalcPot(&atop, mol);

            CrgUnit *crg = mol->getUserData<CrgUnit > ();

            //Change the charges on the molecule mol to the occupied=charged state
            top->CopyChargesOccupied(crg, mol);

            //Compute the EstaticPotentialEnergy for molecule mol if it is charged
            crged = CalcPot(&atop, mol);
            //Copy back the charges as if molecule mol would be neutral so that the loop can pick up the next molecule
            top->CopyCharges(crg, mol);
        }

        //If the site energy is large and positive (crged >> neutr) molecule mol wants to stay neutral
        //This is consistent with marcus_rates.h since w_12 (from 1 to 2) contains (dG_12 + \lambda)^2 and dG_12=e_2-e_1
        crg->setEnergy(crged - neutr);

        //        cout << "Estatic energy [eV] for charged / neutral / crg-neutr=espilon: " << crged << " " << neutr << " " << crged - neutr << "\n";
        cout << "estatic energy [eV] for crgunit " << crg->getId() << " at pos " << crg->GetCom() << " is " << crged - neutr << "\n";

        if (_options->get("options.estatic_params.estatic_method").as<string > () == "dipoles") {
            for (BeadContainer::iterator iter = atop.Beads().begin();
                    iter != atop.Beads().end(); ++iter) {
                Bead *b = *iter;
               // cout << "if mol " << crg->getId() << "at pos " << crg->GetCom() << " is charged, Bead " << b->getId() << " at pos " << b->getPos() << " has charge " << b->getQ() << " and dipole xyz [D]" << *b->getUserData<vec > () << "\n";
                delete b->getUserData<vec > ();
                b->setUserData<void>(NULL);
            }
        }
    }

    atop.Cleanup();

    return true;
}

//Calculate Estatics

double CalcEstatics::CalcPot(Topology *atop, Molecule *mol) //wegen Übergabe per * unten ->
{
    //estatic energy including contributions from all other molecules in eV
    double pot = 0.0;
    //Coulombs constant including conversion factors (elementary charge and nm) so that pot is in eV
    double k_c = 1.602176487e-19 / (1.0e-9 * 8.854187817e-12 * 4.0 * M_PI);

    //Do loop over all other molecules imol that are not mol
    MoleculeContainer::iterator imol;
    for (imol = atop->Molecules().begin(); imol != atop->Molecules().end(); imol++) {
        if (*imol == mol) continue;
        //Check whether PBC have to be taken into account
        //We should replace getUserData by a funtion GetCom for molecules
        vec bcs = atop->BCShortestConnection(mol->getUserData<CrgUnit > ()->GetCom(), (*imol)->getUserData<CrgUnit > ()->GetCom());
        vec dist = (*imol)->getUserData<CrgUnit > ()->GetCom() - mol->getUserData<CrgUnit > ()->GetCom();
        vec diff = bcs - dist;

        //cout<<" s="<<s<<endl;
        for (int i = 0; i < mol->BeadCount(); i++)
            for (int j = 0; j != (*imol)->BeadCount(); j++) {
                Bead *bi = mol->getBead(i);
                Bead *bj = (*imol)->getBead(j);
                //distance vector may have to be shifted by s
                vec r_v = bi->getPos()-(bj->getPos() + diff);
                double r = abs(r_v);
                double qi = bi->getQ();
                double qj = bj->getQ();
                //cout<<bj->getPos()<<r_v<<r<<qi<<qj<<_epsilon_dielectric<<pot<<qi*qj/_epsilon_dielectric*1/r<<endl;
                //pot += k_c * qi * qj / ( (this->*_estatic_method)(r) * r ); //in eV
                pot += k_c * qi * qj / ((this->*_estatic_method)(abs(bcs)) * r); //in eV
            }
    }
    return pot;

}

double CalcEstatics::CalcPot_Dipole(Topology *atop, Molecule *mol) //wegen Übergabe per * unten ->
{
    //estatic energy including contributions from all other molecules in eV
    double pot;
    double pot_qq=0.0;
    double pot_qd=0.0;
    double pot_dd=0.0;
    //Coulombs constant including conversion factors (elementary charge and nm) so that pot is in eV
    double k_cc = 1.602176487e-19 / (1.0e-9 * 8.854187817e-12 * 4.0 * M_PI);
    double k_cd = k_cc * 0.02082; //1 Debeye is 3.33564 e-30 C*m or 0.02082*e*nm
    double k_dd = k_cc * 0.02082*0.02082;
    //Now we have to include interactions of the other molecules among themselves
    //Do loop over all molecules cmol
    MoleculeContainer::iterator cmol;
    //Do loop over all other molecules imol that are not cmol
    MoleculeContainer::iterator imol;
    for (cmol = atop->Molecules().begin(); cmol != atop->Molecules().end(); cmol++) {
        for (imol = atop->Molecules().begin(); imol != atop->Molecules().end(); imol++) {
            //only count interaction if mol_id of c is smaller than mol_id of i
            if ((*imol)->getId() <= (*cmol)->getId()) continue;
            //Check whether PBC have to be taken into account
            //We should replace getUserData by a funtion GetCom for molecules
            vec bcs = atop->BCShortestConnection((*cmol)->getUserData<CrgUnit > ()->GetCom(), (*imol)->getUserData<CrgUnit > ()->GetCom());
            vec dist = (*imol)->getUserData<CrgUnit > ()->GetCom() - (*cmol)->getUserData<CrgUnit > ()->GetCom();
            vec diff = bcs - dist;

            //cout<<" s="<<s<<endl;
            for (int i = 0; i != (*cmol)->BeadCount(); i++)
                for (int j = 0; j != (*imol)->BeadCount(); j++) {
                    Bead *bi = (*cmol)->getBead(i);
                    Bead *bj = (*imol)->getBead(j);
                    //distance vector may have to be shifted by s
                    vec r_v = bi->getPos()-(bj->getPos() + diff); //ri-rj so that r_v points from j to i
                    double r = abs(r_v);
                    double r3 = r * r*r;
                    double qi = bi->getQ();
                    double qj = bj->getQ();
                    vec di = *bi->getUserData<vec > ();
                    vec dj = *bj->getUserData<vec > ();
                    //charge charge interaction in eV
                    pot_qq += k_cc * qi * qj / r;
                    //dipol-charge interaction in eV between charge on i and dipole on j
                    pot_qd += k_cd * qi * (dj.getX() * r_v.getX() + dj.getY() * r_v.getY() + dj.getZ() * r_v.getZ()) / r3;
                    //dipol-charge interaction in eV if charge on j, dipole on i. Note that r_v points from j to i, so -1.0!
                    pot_dd += k_dd * (-1.0) * qj * (di.getX() * r_v.getX() + di.getY() * r_v.getY() + di.getZ() * r_v.getZ()) / r3;
                    //dipole-dipole  interaction
                    pot_dd += k_dd / r3 * (dj.getX() * di.getX() + dj.getY() * di.getY() + dj.getZ() * di.getZ() + 3.0 * (di.getX() * r_v.getX() + di.getY() * r_v.getY() + di.getZ() * r_v.getZ())*(dj.getX() * r_v.getX() + dj.getY() * r_v.getY() + dj.getZ() * r_v.getZ()));

                }
        }
    }
    pot=pot_qq+pot_qd+pot_dd;
    cout << "Q-Q: "<<pot_qq << "    Q-D: "<<pot_qd<< "  D-D: "<< pot_dd<<"  total: "<< pot <<"\n";
    return pot;
}

double CalcEstatics::dist_dep_eps(const double &dist) {
    return _epsilon_dielectric - (_epsilon_dielectric - 1.0) * exp(-_s_eps * dist)*(1.0 + _s_eps * dist + 0.5 * _s_eps * dist * _s_eps * dist);
}

double CalcEstatics::constant_epsilon(const double &dist) {
    return _epsilon_dielectric;
}
<commit_msg>added estatics methods<commit_after>/*
 * File:   calc_estatics.cpp
 * Author: mayfalk
 *
 * Created on May 21, 2010, 11:21 PM
 */

#include <stdlib.h>
#include "estatics.h"
#include <math.h>
#include <list>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <fstream>

void CalcEstatics::Initialize(QMTopology *top, Property *options) {
    _options = options;
    if (options->exists("options.estatic_params.epsilon_dielectric")) {
        _epsilon_dielectric = options->get("options.estatic_params.epsilon_dielectric").as<double>();
    } else {
        _epsilon_dielectric = 3.0;
        cout << "Warning: dielectric constant in not provided, using default" << endl;
    }

    if (options->exists("options.estatic_params.s_eps")) {
        _s_eps = options->get("options.estatic_params.s_eps").as<double>();
    } else {
        _s_eps = 3.0;
        cout << "Warning: s_eps is not provided, using default" << endl;
    }

    if (options->exists("options.estatic_params.estatic_method")) {
        if (options->get("options.estatic_params.estatic_method").as<string > () == "distdep") {
            _estatic_method = &CalcEstatics::dist_dep_eps;
            cout << "Doing distance-dependent-eps estatic with eps " << _epsilon_dielectric << " and s_eps " << _s_eps << endl;
        }
        if (options->get("options.estatic_params.estatic_method").as<string > () == "simple") {
            _estatic_method = &CalcEstatics::constant_epsilon;
            cout << "Doing simple estatic with eps " << _epsilon_dielectric << endl;
        } else if (options->get("options.estatic_params.estatic_method").as<string > () == "dipoles") {
            _estatic_method = &CalcEstatics::constant_epsilon;
            cout << "Doing interactions including dipoles with eps =1 " << endl;
        } else throw std::runtime_error("Error in CalcEstatics::Initialize : no such estatic method, should be simple or distdep");
    } else throw std::runtime_error("Error in CalcEstatics:Initialize : no estatic_method specified");
}

bool CalcEstatics::EvaluateFrame(QMTopology *top) {
    vector<CrgUnit *> lcharges = top->CrgUnits();
    Topology atop;
    atop.setBox(top->getBox());
    for (vector<CrgUnit *>::iterator itl = lcharges.begin(); itl != lcharges.end(); itl++) {
        top->AddAtomisticBeads(*itl, &atop);
    }
    cout << "Number of charge units in top " << lcharges.size() << endl;
    cout << "Number of molecules in atop " << atop.MoleculeCount() << endl;
    double crged, neutr;

    MoleculeContainer::iterator imol;
    for (imol = atop.Molecules().begin(); imol != atop.Molecules().end(); imol++) {
        Molecule *mol = *imol;
        CrgUnit *crg = mol->getUserData<CrgUnit > ();
        //if induced dipoles then directly go to charged system
        if (_options->get("options.estatic_params.estatic_method").as<string > () == "dipoles") {

            //Change the charges on the molecule mol to the occupied=charged state
            top->CopyChargesOccupied(crg, mol);
            //read in the induced dipole moments
            string s;
            int nr = mol->getId();
            string filename = "d_" + boost::lexical_cast<string > (nr);
            ifstream indata;
            indata.open(filename.c_str());
            for (BeadContainer::iterator iter = atop.Beads().begin();
                    iter != atop.Beads().end(); ++iter) { // keep reading until end-of-file
                Bead *b = *iter;
                getline(indata, s);
                Tokenizer tok(s, " ");
                vector<double> v;
                tok.ConvertToVector(v);
                if (v.size() != 3)
                    throw std::ios_base::failure("invalid dipole format. should be dx dy dz in Debeye separated by one space");
                double vx = v[0];
                double vy = v[1];
                double vz = v[2];
                b->setUserData<vec > (new vec(vx, vy, vz));
            }
            indata.close();
            crged = CalcPot_Dipole(&atop, mol);
            neutr = 0.0;
            top->CopyCharges(crg, mol);
        }
            //otherwise do the regular estatics shit
        else {
            //Compute the EstaticPotentialEnergy for molecule mol if it is neutral
            neutr = CalcPot(&atop, mol);

            CrgUnit *crg = mol->getUserData<CrgUnit > ();

            //Change the charges on the molecule mol to the occupied=charged state
            top->CopyChargesOccupied(crg, mol);

            //Compute the EstaticPotentialEnergy for molecule mol if it is charged
            crged = CalcPot(&atop, mol);
            //Copy back the charges as if molecule mol would be neutral so that the loop can pick up the next molecule
            top->CopyCharges(crg, mol);
        }

        //If the site energy is large and positive (crged >> neutr) molecule mol wants to stay neutral
        //This is consistent with marcus_rates.h since w_12 (from 1 to 2) contains (dG_12 + \lambda)^2 and dG_12=e_2-e_1
        crg->setEnergy(crged - neutr);

        //        cout << "Estatic energy [eV] for charged / neutral / crg-neutr=espilon: " << crged << " " << neutr << " " << crged - neutr << "\n";
        cout << "estatic energy [eV] for crgunit " << crg->getId() << " at pos " << crg->GetCom() << " is " << crged - neutr << "\n";

        if (_options->get("options.estatic_params.estatic_method").as<string > () == "dipoles") {
            for (BeadContainer::iterator iter = atop.Beads().begin();
                    iter != atop.Beads().end(); ++iter) {
                Bead *b = *iter;
               // cout << "if mol " << crg->getId() << "at pos " << crg->GetCom() << " is charged, Bead " << b->getId() << " at pos " << b->getPos() << " has charge " << b->getQ() << " and dipole xyz [D]" << *b->getUserData<vec > () << "\n";
                delete b->getUserData<vec > ();
                b->setUserData<void>(NULL);
            }
        }
    }

    atop.Cleanup();

    return true;
}

//Calculate Estatics

double CalcEstatics::CalcPot(Topology *atop, Molecule *mol) //wegen Übergabe per * unten ->
{
    //estatic energy including contributions from all other molecules in eV
    double pot = 0.0;
    //Coulombs constant including conversion factors (elementary charge and nm) so that pot is in eV
    double k_c = 1.602176487e-19 / (1.0e-9 * 8.854187817e-12 * 4.0 * M_PI);

    //Do loop over all other molecules imol that are not mol
    MoleculeContainer::iterator imol;
    for (imol = atop->Molecules().begin(); imol != atop->Molecules().end(); imol++) {
        if (*imol == mol) continue;
        //Check whether PBC have to be taken into account
        //We should replace getUserData by a funtion GetCom for molecules
        vec bcs = atop->BCShortestConnection(mol->getUserData<CrgUnit > ()->GetCom(), (*imol)->getUserData<CrgUnit > ()->GetCom());
        vec dist = (*imol)->getUserData<CrgUnit > ()->GetCom() - mol->getUserData<CrgUnit > ()->GetCom();
        vec diff = bcs - dist;

        //cout<<" s="<<s<<endl;
        for (int i = 0; i < mol->BeadCount(); i++)
            for (int j = 0; j != (*imol)->BeadCount(); j++) {
                Bead *bi = mol->getBead(i);
                Bead *bj = (*imol)->getBead(j);
                //distance vector may have to be shifted by s
                vec r_v = bi->getPos()-(bj->getPos() + diff);
                double r = abs(r_v);
                double qi = bi->getQ();
                double qj = bj->getQ();
                //cout<<bj->getPos()<<r_v<<r<<qi<<qj<<_epsilon_dielectric<<pot<<qi*qj/_epsilon_dielectric*1/r<<endl;
                //pot += k_c * qi * qj / ( (this->*_estatic_method)(r) * r ); //in eV
                pot += k_c * qi * qj / ((this->*_estatic_method)(abs(bcs)) * r); //in eV
            }
    }
    return pot;

}

double CalcEstatics::CalcPot_Dipole(Topology *atop, Molecule *mol) //wegen Übergabe per * unten ->
{
    //estatic energy including contributions from all other molecules in eV
    double pot;
    double pot_qq=0.0;
    double pot_qd=0.0;
    double pot_dd=0.0;
    //Coulombs constant including conversion factors (elementary charge and nm) so that pot is in eV
    double k_cc = 1.602176487e-19 / (1.0e-9 * 8.854187817e-12 * 4.0 * M_PI);
    double k_cd = k_cc * 0.02082; //1 Debeye is 3.33564 e-30 C*m or 0.02082*e*nm
    double k_dd = k_cc * 0.02082*0.02082;
    //Now we have to include interactions of the other molecules among themselves
    //Do loop over all molecules cmol
    MoleculeContainer::iterator cmol;
    //Do loop over all other molecules imol that are not cmol
   /*
    MoleculeContainer::iterator imol;
    for (cmol = atop->Molecules().begin(); cmol != atop->Molecules().end(); cmol++) {
        for (imol = atop->Molecules().begin(); imol != atop->Molecules().end(); imol++) {
            //only count interaction if mol_id of c is smaller than mol_id of i
            if ((*imol)->getId() <= (*cmol)->getId()) continue;
            //Check whether PBC have to be taken into account
            //We should replace getUserData by a funtion GetCom for molecules
            vec bcs = atop->BCShortestConnection((*cmol)->getUserData<CrgUnit > ()->GetCom(), (*imol)->getUserData<CrgUnit > ()->GetCom());
            vec dist = (*imol)->getUserData<CrgUnit > ()->GetCom() - (*cmol)->getUserData<CrgUnit > ()->GetCom();
            vec diff = bcs - dist;

            //cout<<" s="<<s<<endl;
            for (int i = 0; i != (*cmol)->BeadCount(); i++)
                for (int j = 0; j != (*imol)->BeadCount(); j++) {
                    Bead *bi = (*cmol)->getBead(i);
                    Bead *bj = (*imol)->getBead(j);
                    //distance vector may have to be shifted by s
                    vec r_v = bi->getPos()-(bj->getPos() + diff); //ri-rj so that r_v points from j to i
                    double r = abs(r_v);
                    double r3 = r * r*r;
                    double qi = bi->getQ();
                    double qj = bj->getQ();
                    vec di = *bi->getUserData<vec > ();
                    vec dj = *bj->getUserData<vec > ();
                    //charge charge interaction in eV
                    pot_qq += k_cc * qi * qj / r;
                    //dipol-charge interaction in eV between charge on i and dipole on j
                    pot_qd += k_cd * qi * (dj.getX() * r_v.getX() + dj.getY() * r_v.getY() + dj.getZ() * r_v.getZ()) / r3;
                    //dipol-charge interaction in eV if charge on j, dipole on i. Note that r_v points from j to i, so -1.0!
                    pot_dd += k_dd * (-1.0) * qj * (di.getX() * r_v.getX() + di.getY() * r_v.getY() + di.getZ() * r_v.getZ()) / r3;
                    //dipole-dipole  interaction
                    pot_dd += k_dd / r3 * (dj.getX() * di.getX() + dj.getY() * di.getY() + dj.getZ() * di.getZ() + 3.0 * (di.getX() * r_v.getX() + di.getY() * r_v.getY() + di.getZ() * r_v.getZ())*(dj.getX() * r_v.getX() + dj.getY() * r_v.getY() + dj.getZ() * r_v.getZ()));

                }
        }
    }
    pot=pot_qq+pot_qd+pot_dd;
    cout << "Q-Q: "<<pot_qq << "    Q-D: "<<pot_qd<< "  D-D: "<< pot_dd<<"  total: "<< pot <<"\n";
*/
    int nr = mol->getId();
            string filename = "xyz_a" + boost::lexical_cast<string > (nr);
            FILE * data;
            //ofstream data
                //data.open(filename.c_str());
            data=fopen(filename.c_str(),"w");
     MoleculeContainer::iterator dmol;
         for (dmol = atop->Molecules().begin(); dmol != atop->Molecules().end(); dmol++) {

        //if (*dmol == mol) continue;
        //Check whether PBC have to be taken into account
        //We should replace getUserData by a funtion GetCom for molecules
        vec bcs = atop->BCShortestConnection(mol->getUserData<CrgUnit > ()->GetCom(), (*dmol)->getUserData<CrgUnit > ()->GetCom());
        vec dist = (*dmol)->getUserData<CrgUnit > ()->GetCom() - mol->getUserData<CrgUnit > ()->GetCom();
        vec diff = bcs - dist;
        for (int j = 0; j != (*dmol)->BeadCount(); j++) {
                Bead *bj = (*dmol)->getBead(j);
                //distance vector may have to be shifted by s
                vec r_v = mol->getUserData<CrgUnit > ()->GetCom()-(bj->getPos() + diff);
               // data << mol->getId()<<" "<<(*dmol)->getId()<<" "<< r_v.getX()*10.0 <<" "<< r_v.getY()*10.0 <<" "<< r_v.getZ()*10.0 <<"\n";
                 fprintf(data, "%d %d %.6f %.6f %.6f\n",mol->getId(),(*dmol)->getId(),r_v.getX()*10.0,r_v.getY()*10.0,r_v.getZ()*10.0);
        }

    }
    fclose(data);
    //data.close();
    return pot;

}

double CalcEstatics::dist_dep_eps(const double &dist) {
    return _epsilon_dielectric - (_epsilon_dielectric - 1.0) * exp(-_s_eps * dist)*(1.0 + _s_eps * dist + 0.5 * _s_eps * dist * _s_eps * dist);
}

double CalcEstatics::constant_epsilon(const double &dist) {
    return _epsilon_dielectric;
}
<|endoftext|>


<commit_before>//===-- X86TargetAsmInfo.cpp - X86 asm properties ---------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by James M. Laskey and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the X86TargetAsmInfo properties.
//
//===----------------------------------------------------------------------===//

#include "X86TargetAsmInfo.h"
#include "X86TargetMachine.h"
#include "X86Subtarget.h"

using namespace llvm;

X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) {
  const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();

  // FIXME - Should be simplified.

  switch (Subtarget->TargetType) {
  case X86Subtarget::isDarwin:
    AlignmentIsInBytes = false;
    GlobalPrefix = "_";
    if (!Subtarget->is64Bit())
      Data64bitsDirective = 0;       // we can't emit a 64-bit unit
    ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
    PrivateGlobalPrefix = "L";     // Marker for constant pool idxs
    ConstantPoolSection = "\t.const\n";
    JumpTableDataSection = "\t.const\n";
    CStringSection = "\t.cstring";
    FourByteConstantSection = "\t.literal4\n";
    EightByteConstantSection = "\t.literal8\n";
    if (Subtarget->is64Bit())
      SixteenByteConstantSection = "\t.literal16\n";
    LCOMMDirective = "\t.lcomm\t";
    COMMDirectiveTakesAlignment = false;
    HasDotTypeDotSizeDirective = false;
    StaticCtorsSection = ".mod_init_func";
    StaticDtorsSection = ".mod_term_func";
    InlineAsmStart = "# InlineAsm Start";
    InlineAsmEnd = "# InlineAsm End";
    SetDirective = "\t.set";
    UsedDirective = "\t.no_dead_strip\t";

    NeedsSet = true;
    DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
    DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
    DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
    DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
    DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
    DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
    DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
    DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
    DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
    DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
    DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
    break;

  case X86Subtarget::isELF:
    // Set up DWARF directives
    HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)
    // bool HasLEB128; // Defaults to false.
    // hasDotLoc - True if target asm supports .loc directives.
    // bool HasDotLoc; // Defaults to false.
    // HasDotFile - True if target asm supports .file directives.
    // bool HasDotFile; // Defaults to false.
    PrivateGlobalPrefix = ".";  // Prefix for private global symbols
    DwarfRequiresFrameSection = false;
    DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"\",@progbits";
    DwarfInfoSection =    "\t.section\t.debug_info,\"\",@progbits";
    DwarfLineSection =    "\t.section\t.debug_line,\"\",@progbits";
    DwarfFrameSection =   "\t.section\t.debug_frame,\"\",@progbits";
    DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits";
    DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits";
    DwarfStrSection =     "\t.section\t.debug_str,\"\",@progbits";
    DwarfLocSection =     "\t.section\t.debug_loc,\"\",@progbits";
    DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits";
    DwarfRangesSection =  "\t.section\t.debug_ranges,\"\",@progbits";
    DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits";
    break;

  case X86Subtarget::isCygwin:
    GlobalPrefix = "_";
    COMMDirectiveTakesAlignment = false;
    HasDotTypeDotSizeDirective = false;
    StaticCtorsSection = "\t.section .ctors,\"aw\"";
    StaticDtorsSection = "\t.section .dtors,\"aw\"";

    // Set up DWARF directives
    HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)
    PrivateGlobalPrefix = "L";  // Prefix for private global symbols
    DwarfRequiresFrameSection = false;
    DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"dr\"";
    DwarfInfoSection =    "\t.section\t.debug_info,\"dr\"";
    DwarfLineSection =    "\t.section\t.debug_line,\"dr\"";
    DwarfFrameSection =   "\t.section\t.debug_frame,\"dr\"";
    DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"dr\"";
    DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"dr\"";
    DwarfStrSection =     "\t.section\t.debug_str,\"dr\"";
    DwarfLocSection =     "\t.section\t.debug_loc,\"dr\"";
    DwarfARangesSection = "\t.section\t.debug_aranges,\"dr\"";
    DwarfRangesSection =  "\t.section\t.debug_ranges,\"dr\"";
    DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"dr\"";
    break;

    break;
  case X86Subtarget::isWindows:
    GlobalPrefix = "_";
    HasDotTypeDotSizeDirective = false;
    break;
  default: break;
  }

  if (Subtarget->isFlavorIntel()) {
    GlobalPrefix = "_";
    CommentString = ";";

    PrivateGlobalPrefix = "$";
    AlignDirective = "\talign\t";
    ZeroDirective = "\tdb\t";
    ZeroDirectiveSuffix = " dup(0)";
    AsciiDirective = "\tdb\t";
    AscizDirective = 0;
    Data8bitsDirective = "\tdb\t";
    Data16bitsDirective = "\tdw\t";
    Data32bitsDirective = "\tdd\t";
    Data64bitsDirective = "\tdq\t";
    HasDotTypeDotSizeDirective = false;

    TextSection = "_text";
    DataSection = "_data";
    SwitchToSectionDirective = "";
    TextSectionStartSuffix = "\tsegment 'CODE'";
    DataSectionStartSuffix = "\tsegment 'DATA'";
    SectionEndDirectiveSuffix = "\tends\n";
  }
}

<commit_msg>X86 asm -> gcc asm translation table (incomplete)<commit_after>//===-- X86TargetAsmInfo.cpp - X86 asm properties ---------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by James M. Laskey and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the X86TargetAsmInfo properties.
//
//===----------------------------------------------------------------------===//

#include "X86TargetAsmInfo.h"
#include "X86TargetMachine.h"
#include "X86Subtarget.h"
#include <iostream>

using namespace llvm;

static const char* x86_asm_table[] = {"{si}", "S",
                                      "{di}", "D",
                                      "{ax}", "a",
                                      "{cx}", "c",
                                      "q",    "q",
                                      "r",    "r",
                                      "m",    "m",
                                      "{memory}", "memory",
                                      "{flags}", "",
                                      "{dirflag}", "",
                                      "{fpsr}", "",
                                      "{cc}", "cc",
                                      0,0};

X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) {
  const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();

  // FIXME - Should be simplified.

  AsmTransCBE = x86_asm_table;

  switch (Subtarget->TargetType) {
  case X86Subtarget::isDarwin:
    AlignmentIsInBytes = false;
    GlobalPrefix = "_";
    if (!Subtarget->is64Bit())
      Data64bitsDirective = 0;       // we can't emit a 64-bit unit
    ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
    PrivateGlobalPrefix = "L";     // Marker for constant pool idxs
    ConstantPoolSection = "\t.const\n";
    JumpTableDataSection = "\t.const\n";
    CStringSection = "\t.cstring";
    FourByteConstantSection = "\t.literal4\n";
    EightByteConstantSection = "\t.literal8\n";
    if (Subtarget->is64Bit())
      SixteenByteConstantSection = "\t.literal16\n";
    LCOMMDirective = "\t.lcomm\t";
    COMMDirectiveTakesAlignment = false;
    HasDotTypeDotSizeDirective = false;
    StaticCtorsSection = ".mod_init_func";
    StaticDtorsSection = ".mod_term_func";
    InlineAsmStart = "# InlineAsm Start";
    InlineAsmEnd = "# InlineAsm End";
    SetDirective = "\t.set";
    UsedDirective = "\t.no_dead_strip\t";

    NeedsSet = true;
    DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
    DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
    DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
    DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
    DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
    DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
    DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
    DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
    DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
    DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
    DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
    break;

  case X86Subtarget::isELF:
    // Set up DWARF directives
    HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)
    // bool HasLEB128; // Defaults to false.
    // hasDotLoc - True if target asm supports .loc directives.
    // bool HasDotLoc; // Defaults to false.
    // HasDotFile - True if target asm supports .file directives.
    // bool HasDotFile; // Defaults to false.
    PrivateGlobalPrefix = ".";  // Prefix for private global symbols
    DwarfRequiresFrameSection = false;
    DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"\",@progbits";
    DwarfInfoSection =    "\t.section\t.debug_info,\"\",@progbits";
    DwarfLineSection =    "\t.section\t.debug_line,\"\",@progbits";
    DwarfFrameSection =   "\t.section\t.debug_frame,\"\",@progbits";
    DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits";
    DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits";
    DwarfStrSection =     "\t.section\t.debug_str,\"\",@progbits";
    DwarfLocSection =     "\t.section\t.debug_loc,\"\",@progbits";
    DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits";
    DwarfRangesSection =  "\t.section\t.debug_ranges,\"\",@progbits";
    DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits";
    break;

  case X86Subtarget::isCygwin:
    GlobalPrefix = "_";
    COMMDirectiveTakesAlignment = false;
    HasDotTypeDotSizeDirective = false;
    StaticCtorsSection = "\t.section .ctors,\"aw\"";
    StaticDtorsSection = "\t.section .dtors,\"aw\"";

    // Set up DWARF directives
    HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)
    PrivateGlobalPrefix = "L";  // Prefix for private global symbols
    DwarfRequiresFrameSection = false;
    DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"dr\"";
    DwarfInfoSection =    "\t.section\t.debug_info,\"dr\"";
    DwarfLineSection =    "\t.section\t.debug_line,\"dr\"";
    DwarfFrameSection =   "\t.section\t.debug_frame,\"dr\"";
    DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"dr\"";
    DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"dr\"";
    DwarfStrSection =     "\t.section\t.debug_str,\"dr\"";
    DwarfLocSection =     "\t.section\t.debug_loc,\"dr\"";
    DwarfARangesSection = "\t.section\t.debug_aranges,\"dr\"";
    DwarfRangesSection =  "\t.section\t.debug_ranges,\"dr\"";
    DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"dr\"";
    break;

    break;
  case X86Subtarget::isWindows:
    GlobalPrefix = "_";
    HasDotTypeDotSizeDirective = false;
    break;
  default: break;
  }

  if (Subtarget->isFlavorIntel()) {
    GlobalPrefix = "_";
    CommentString = ";";

    PrivateGlobalPrefix = "$";
    AlignDirective = "\talign\t";
    ZeroDirective = "\tdb\t";
    ZeroDirectiveSuffix = " dup(0)";
    AsciiDirective = "\tdb\t";
    AscizDirective = 0;
    Data8bitsDirective = "\tdb\t";
    Data16bitsDirective = "\tdw\t";
    Data32bitsDirective = "\tdd\t";
    Data64bitsDirective = "\tdq\t";
    HasDotTypeDotSizeDirective = false;

    TextSection = "_text";
    DataSection = "_data";
    SwitchToSectionDirective = "";
    TextSectionStartSuffix = "\tsegment 'CODE'";
    DataSectionStartSuffix = "\tsegment 'DATA'";
    SectionEndDirectiveSuffix = "\tends\n";
  }
}

<|endoftext|>


<commit_before>//===- StripSymbols.cpp - Strip symbols and debug info from a module ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The StripSymbols transformation implements code stripping. Specifically, it
// can delete:
//
//   * names for virtual registers
//   * symbols for internal globals and functions
//   * debug information
//
// Note that this transformation makes code much less readable, so it should
// only be used in situations where the 'strip' utility would be used, such as
// reducing code size or making it harder to reverse engineer code.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/SmallPtrSet.h"
using namespace llvm;

namespace {
  class VISIBILITY_HIDDEN StripSymbols : public ModulePass {
    bool OnlyDebugInfo;
  public:
    static char ID; // Pass identification, replacement for typeid
    explicit StripSymbols(bool ODI = false)
      : ModulePass(&ID), OnlyDebugInfo(ODI) {}

    virtual bool runOnModule(Module &M);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
    }
  };

  class VISIBILITY_HIDDEN StripNonDebugSymbols : public ModulePass {
  public:
    static char ID; // Pass identification, replacement for typeid
    explicit StripNonDebugSymbols()
      : ModulePass(&ID) {}

    virtual bool runOnModule(Module &M);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
    }
  };

  class VISIBILITY_HIDDEN StripDebugDeclare : public ModulePass {
  public:
    static char ID; // Pass identification, replacement for typeid
    explicit StripDebugDeclare()
      : ModulePass(&ID) {}

    virtual bool runOnModule(Module &M);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
    }
  };
}

char StripSymbols::ID = 0;
static RegisterPass<StripSymbols>
X("strip", "Strip all symbols from a module");

ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) {
  return new StripSymbols(OnlyDebugInfo);
}

char StripNonDebugSymbols::ID = 0;
static RegisterPass<StripNonDebugSymbols>
Y("strip-nondebug", "Strip all symbols, except dbg symbols, from a module");

ModulePass *llvm::createStripNonDebugSymbolsPass() {
  return new StripNonDebugSymbols();
}

char StripDebugDeclare::ID = 0;
static RegisterPass<StripDebugDeclare>
Z("strip-debug-declare", "Strip all llvm.dbg.declare intrinsics");

ModulePass *llvm::createStripDebugDeclarePass() {
  return new StripDebugDeclare();
}

/// OnlyUsedBy - Return true if V is only used by Usr.
static bool OnlyUsedBy(Value *V, Value *Usr) {
  for(Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
    User *U = *I;
    if (U != Usr)
      return false;
  }
  return true;
}

static void RemoveDeadConstant(Constant *C) {
  assert(C->use_empty() && "Constant is not dead!");
  SmallPtrSet<Constant *, 4> Operands;
  for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
    if (isa<DerivedType>(C->getOperand(i)->getType()) &&
        OnlyUsedBy(C->getOperand(i), C))
      Operands.insert(C->getOperand(i));
  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
    if (!GV->hasLocalLinkage()) return;   // Don't delete non static globals.
    GV->eraseFromParent();
  }
  else if (!isa<Function>(C))
    if (isa<CompositeType>(C->getType()))
      C->destroyConstant();

  // If the constant referenced anything, see if we can delete it as well.
  for (SmallPtrSet<Constant *, 4>::iterator OI = Operands.begin(),
         OE = Operands.end(); OI != OE; ++OI)
    RemoveDeadConstant(*OI);
}

// Strip the symbol table of its names.
//
static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
  for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
    Value *V = VI->getValue();
    ++VI;
    if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) {
      if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg"))
        // Set name to "", removing from symbol table!
        V->setName("");
    }
  }
}

// Strip the symbol table of its names.
static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) {
  for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) {
    if (PreserveDbgInfo && strncmp(TI->first.c_str(), "llvm.dbg", 8) == 0)
      ++TI;
    else
      ST.remove(TI++);
  }
}

/// Find values that are marked as llvm.used.
static void findUsedValues(GlobalVariable *LLVMUsed,
                           SmallPtrSet<const GlobalValue*, 8> &UsedValues) {
  if (LLVMUsed == 0) return;
  UsedValues.insert(LLVMUsed);

  ConstantArray *Inits = dyn_cast<ConstantArray>(LLVMUsed->getInitializer());
  if (Inits == 0) return;

  for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
    if (GlobalValue *GV =
          dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
      UsedValues.insert(GV);
}

/// StripSymbolNames - Strip symbol names.
static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {

  SmallPtrSet<const GlobalValue*, 8> llvmUsedValues;
  findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues);
  findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues);

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I) {
    if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0)
      if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg"))
        I->setName("");     // Internal symbols can't participate in linkage
  }

  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0)
      if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg"))
        I->setName("");     // Internal symbols can't participate in linkage
    StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo);
  }

  // Remove all names from types.
  StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo);

  return true;
}

// StripDebugInfo - Strip debug info in the module if it exists.
// To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and
// llvm.dbg.region.end calls, and any globals they point to if now dead.
static bool StripDebugInfo(Module &M) {

  // Remove all of the calls to the debugger intrinsics, and remove them from
  // the module.
  Function *FuncStart = M.getFunction("llvm.dbg.func.start");
  Function *StopPoint = M.getFunction("llvm.dbg.stoppoint");
  Function *RegionStart = M.getFunction("llvm.dbg.region.start");
  Function *RegionEnd = M.getFunction("llvm.dbg.region.end");
  Function *Declare = M.getFunction("llvm.dbg.declare");

  if (FuncStart) {
    while (!FuncStart->use_empty()) {
      CallInst *CI = cast<CallInst>(FuncStart->use_back());
      CI->eraseFromParent();
    }
    FuncStart->eraseFromParent();
  }
  if (StopPoint) {
    while (!StopPoint->use_empty()) {
      CallInst *CI = cast<CallInst>(StopPoint->use_back());
      CI->eraseFromParent();
    }
    StopPoint->eraseFromParent();
  }
  if (RegionStart) {
    while (!RegionStart->use_empty()) {
      CallInst *CI = cast<CallInst>(RegionStart->use_back());
      CI->eraseFromParent();
    }
    RegionStart->eraseFromParent();
  }
  if (RegionEnd) {
    while (!RegionEnd->use_empty()) {
      CallInst *CI = cast<CallInst>(RegionEnd->use_back());
      CI->eraseFromParent();
    }
    RegionEnd->eraseFromParent();
  }
  if (Declare) {
    while (!Declare->use_empty()) {
      CallInst *CI = cast<CallInst>(Declare->use_back());
      CI->eraseFromParent();
    }
    Declare->eraseFromParent();
  }

  NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv");
  if (NMD)
    NMD->eraseFromParent();

  // Remove dead metadata.
  M.getContext().RemoveDeadMetadata();
  return true;
}

bool StripSymbols::runOnModule(Module &M) {
  bool Changed = false;
  Changed |= StripDebugInfo(M);
  if (!OnlyDebugInfo)
    Changed |= StripSymbolNames(M, false);
  return Changed;
}

bool StripNonDebugSymbols::runOnModule(Module &M) {
  return StripSymbolNames(M, true);
}

bool StripDebugDeclare::runOnModule(Module &M) {

  Function *Declare = M.getFunction("llvm.dbg.declare");
  std::vector<Constant*> DeadConstants;

  if (Declare) {
    while (!Declare->use_empty()) {
      CallInst *CI = cast<CallInst>(Declare->use_back());
      Value *Arg1 = CI->getOperand(1);
      Value *Arg2 = CI->getOperand(2);
      assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
      CI->eraseFromParent();
      if (Arg1->use_empty()) {
        if (Constant *C = dyn_cast<Constant>(Arg1))
          DeadConstants.push_back(C);
        else
          RecursivelyDeleteTriviallyDeadInstructions(Arg1);
      }
      if (Arg2->use_empty())
        if (Constant *C = dyn_cast<Constant>(Arg2))
          DeadConstants.push_back(C);
    }
    Declare->eraseFromParent();
  }

  // Delete all llvm.dbg.global_variables.
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I) {
    GlobalVariable *GV = dyn_cast<GlobalVariable>(I);
    if (!GV) continue;
    if (GV->use_empty() && GV->getName().startswith("llvm.dbg.global_variable"))
      DeadConstants.push_back(GV);
  }

  while (!DeadConstants.empty()) {
    Constant *C = DeadConstants.back();
    DeadConstants.pop_back();
    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
      if (GV->hasLocalLinkage())
        RemoveDeadConstant(GV);
    }
    else
      RemoveDeadConstant(C);
  }

  return true;
}
<commit_msg>Remove VISIBILITY_HIDDEN from this file.<commit_after>//===- StripSymbols.cpp - Strip symbols and debug info from a module ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The StripSymbols transformation implements code stripping. Specifically, it
// can delete:
//
//   * names for virtual registers
//   * symbols for internal globals and functions
//   * debug information
//
// Note that this transformation makes code much less readable, so it should
// only be used in situations where the 'strip' utility would be used, such as
// reducing code size or making it harder to reverse engineer code.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/SmallPtrSet.h"
using namespace llvm;

namespace {
  class StripSymbols : public ModulePass {
    bool OnlyDebugInfo;
  public:
    static char ID; // Pass identification, replacement for typeid
    explicit StripSymbols(bool ODI = false)
      : ModulePass(&ID), OnlyDebugInfo(ODI) {}

    virtual bool runOnModule(Module &M);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
    }
  };

  class StripNonDebugSymbols : public ModulePass {
  public:
    static char ID; // Pass identification, replacement for typeid
    explicit StripNonDebugSymbols()
      : ModulePass(&ID) {}

    virtual bool runOnModule(Module &M);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
    }
  };

  class StripDebugDeclare : public ModulePass {
  public:
    static char ID; // Pass identification, replacement for typeid
    explicit StripDebugDeclare()
      : ModulePass(&ID) {}

    virtual bool runOnModule(Module &M);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
    }
  };
}

char StripSymbols::ID = 0;
static RegisterPass<StripSymbols>
X("strip", "Strip all symbols from a module");

ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) {
  return new StripSymbols(OnlyDebugInfo);
}

char StripNonDebugSymbols::ID = 0;
static RegisterPass<StripNonDebugSymbols>
Y("strip-nondebug", "Strip all symbols, except dbg symbols, from a module");

ModulePass *llvm::createStripNonDebugSymbolsPass() {
  return new StripNonDebugSymbols();
}

char StripDebugDeclare::ID = 0;
static RegisterPass<StripDebugDeclare>
Z("strip-debug-declare", "Strip all llvm.dbg.declare intrinsics");

ModulePass *llvm::createStripDebugDeclarePass() {
  return new StripDebugDeclare();
}

/// OnlyUsedBy - Return true if V is only used by Usr.
static bool OnlyUsedBy(Value *V, Value *Usr) {
  for(Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
    User *U = *I;
    if (U != Usr)
      return false;
  }
  return true;
}

static void RemoveDeadConstant(Constant *C) {
  assert(C->use_empty() && "Constant is not dead!");
  SmallPtrSet<Constant *, 4> Operands;
  for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
    if (isa<DerivedType>(C->getOperand(i)->getType()) &&
        OnlyUsedBy(C->getOperand(i), C))
      Operands.insert(C->getOperand(i));
  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
    if (!GV->hasLocalLinkage()) return;   // Don't delete non static globals.
    GV->eraseFromParent();
  }
  else if (!isa<Function>(C))
    if (isa<CompositeType>(C->getType()))
      C->destroyConstant();

  // If the constant referenced anything, see if we can delete it as well.
  for (SmallPtrSet<Constant *, 4>::iterator OI = Operands.begin(),
         OE = Operands.end(); OI != OE; ++OI)
    RemoveDeadConstant(*OI);
}

// Strip the symbol table of its names.
//
static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
  for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
    Value *V = VI->getValue();
    ++VI;
    if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) {
      if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg"))
        // Set name to "", removing from symbol table!
        V->setName("");
    }
  }
}

// Strip the symbol table of its names.
static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) {
  for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) {
    if (PreserveDbgInfo && strncmp(TI->first.c_str(), "llvm.dbg", 8) == 0)
      ++TI;
    else
      ST.remove(TI++);
  }
}

/// Find values that are marked as llvm.used.
static void findUsedValues(GlobalVariable *LLVMUsed,
                           SmallPtrSet<const GlobalValue*, 8> &UsedValues) {
  if (LLVMUsed == 0) return;
  UsedValues.insert(LLVMUsed);

  ConstantArray *Inits = dyn_cast<ConstantArray>(LLVMUsed->getInitializer());
  if (Inits == 0) return;

  for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
    if (GlobalValue *GV =
          dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
      UsedValues.insert(GV);
}

/// StripSymbolNames - Strip symbol names.
static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {

  SmallPtrSet<const GlobalValue*, 8> llvmUsedValues;
  findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues);
  findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues);

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I) {
    if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0)
      if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg"))
        I->setName("");     // Internal symbols can't participate in linkage
  }

  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0)
      if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg"))
        I->setName("");     // Internal symbols can't participate in linkage
    StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo);
  }

  // Remove all names from types.
  StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo);

  return true;
}

// StripDebugInfo - Strip debug info in the module if it exists.
// To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and
// llvm.dbg.region.end calls, and any globals they point to if now dead.
static bool StripDebugInfo(Module &M) {

  // Remove all of the calls to the debugger intrinsics, and remove them from
  // the module.
  Function *FuncStart = M.getFunction("llvm.dbg.func.start");
  Function *StopPoint = M.getFunction("llvm.dbg.stoppoint");
  Function *RegionStart = M.getFunction("llvm.dbg.region.start");
  Function *RegionEnd = M.getFunction("llvm.dbg.region.end");
  Function *Declare = M.getFunction("llvm.dbg.declare");

  if (FuncStart) {
    while (!FuncStart->use_empty()) {
      CallInst *CI = cast<CallInst>(FuncStart->use_back());
      CI->eraseFromParent();
    }
    FuncStart->eraseFromParent();
  }
  if (StopPoint) {
    while (!StopPoint->use_empty()) {
      CallInst *CI = cast<CallInst>(StopPoint->use_back());
      CI->eraseFromParent();
    }
    StopPoint->eraseFromParent();
  }
  if (RegionStart) {
    while (!RegionStart->use_empty()) {
      CallInst *CI = cast<CallInst>(RegionStart->use_back());
      CI->eraseFromParent();
    }
    RegionStart->eraseFromParent();
  }
  if (RegionEnd) {
    while (!RegionEnd->use_empty()) {
      CallInst *CI = cast<CallInst>(RegionEnd->use_back());
      CI->eraseFromParent();
    }
    RegionEnd->eraseFromParent();
  }
  if (Declare) {
    while (!Declare->use_empty()) {
      CallInst *CI = cast<CallInst>(Declare->use_back());
      CI->eraseFromParent();
    }
    Declare->eraseFromParent();
  }

  NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv");
  if (NMD)
    NMD->eraseFromParent();

  // Remove dead metadata.
  M.getContext().RemoveDeadMetadata();
  return true;
}

bool StripSymbols::runOnModule(Module &M) {
  bool Changed = false;
  Changed |= StripDebugInfo(M);
  if (!OnlyDebugInfo)
    Changed |= StripSymbolNames(M, false);
  return Changed;
}

bool StripNonDebugSymbols::runOnModule(Module &M) {
  return StripSymbolNames(M, true);
}

bool StripDebugDeclare::runOnModule(Module &M) {

  Function *Declare = M.getFunction("llvm.dbg.declare");
  std::vector<Constant*> DeadConstants;

  if (Declare) {
    while (!Declare->use_empty()) {
      CallInst *CI = cast<CallInst>(Declare->use_back());
      Value *Arg1 = CI->getOperand(1);
      Value *Arg2 = CI->getOperand(2);
      assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
      CI->eraseFromParent();
      if (Arg1->use_empty()) {
        if (Constant *C = dyn_cast<Constant>(Arg1))
          DeadConstants.push_back(C);
        else
          RecursivelyDeleteTriviallyDeadInstructions(Arg1);
      }
      if (Arg2->use_empty())
        if (Constant *C = dyn_cast<Constant>(Arg2))
          DeadConstants.push_back(C);
    }
    Declare->eraseFromParent();
  }

  // Delete all llvm.dbg.global_variables.
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I) {
    GlobalVariable *GV = dyn_cast<GlobalVariable>(I);
    if (!GV) continue;
    if (GV->use_empty() && GV->getName().startswith("llvm.dbg.global_variable"))
      DeadConstants.push_back(GV);
  }

  while (!DeadConstants.empty()) {
    Constant *C = DeadConstants.back();
    DeadConstants.pop_back();
    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
      if (GV->hasLocalLinkage())
        RemoveDeadConstant(GV);
    }
    else
      RemoveDeadConstant(C);
  }

  return true;
}
<|endoftext|>


<commit_before>// BSD 2-Clause License, see github.com/ma16/rpio

#include "Spi0.h"
#include <vector>

static uint32_t msb32(uint8_t const *p)
{
    uint32_t i = p[0] ;
    i <<= 8 ; i |= p[1] ;
    i <<= 8 ; i |= p[2] ;
    i <<= 8 ; i |= p[3] ;
    return i ;
}

static uint32_t reverse(uint32_t i)
{
    i = (i & 0xffff0000) >> 16 | (i & 0x0000ffff) << 16 ;
    i = (i & 0xff00ff00) >>  8 | (i & 0x00ff00ff) <<  8 ;
    i = (i & 0xf0f0f0f0) >>  4 | (i & 0x0f0f0f0f) <<  4 ;
    i = (i & 0xcccccccc) >>  2 | (i & 0x33333333) <<  2 ;
    i = (i & 0xaaaaaaaa) >>  1 | (i & 0x55555555) <<  1 ;
    return i ;
}

Device::Mcp3008::Spi0::Sample24
Device::Mcp3008::Spi0::query24(Circuit::Source source)
{
    // 17-bit dialog
    uint8_t tx[4] = {0} ; // MOSI: 1 + SOURCE:4 + ANY:12 (+ANY:7)
    tx[0] = static_cast<uint8_t>(0x80 | (source.value() << 3)) ;
    uint8_t rx[4] ; // MISO: Hi:6 + Lo:1 + MSB:10 (+Lo:7)
    this->spi.transceive(3,tx,rx) ;
    // SPI0 transfers are a multiple of 8-bit. Thus, 17 bits become
    // 24 bits and so we're going to receive also 7 LSB bits of the
    // sample. We use 32-bit buffers (instead of 24-bit) because of
    // the msb32() function.
    return Sample24(msb32(rx)) ;
}

Device::Mcp3008::Circuit::Sample
Device::Mcp3008::Spi0::Sample24::fetch() const
{
    // pos. 7-16
    return Circuit::Sample::coset(this->i >> 15) ;
}

Device::Mcp3008::Spi0::Error
Device::Mcp3008::Spi0::Sample24::verify() const
{
    Error error ;
    // 7-bit head
    error.head = 0 != (0xfe000000 & (this->i ^ 0xfc000000)) ;
    auto msb =         this->i  >> 15 ; // pos.  7-16
    auto lsb = reverse(this->i) >> 16 ; // pos. 25-16
    // 9 + 1 + 7 bit sample
    error.mismatch = 0 != (0xff & (msb ^ lsb)) ;
    error.tail = 0 ;
    return error ;
}

Device::Mcp3008::Spi0::Sample32
Device::Mcp3008::Spi0::query32(Circuit::Source source)
{
    // 26-bit dialog
    uint8_t tx[4] = {0} ; // MOSI: 1 + SOURCE:4 + ANY:21 (+ANY:6)
    tx[0] = static_cast<uint8_t>(0x80 | (source.value() << 3)) ;
    uint8_t rx[4] ; // MISO: Hi:6 + Lo:1 + MSB:10 + LSB:9 (+Lo:6)
    this->spi.transceive(4,tx,rx) ;
    // SPI0 transfers are a multiple of 8-bit. Thus, 26 bits become
    // 32 bits and so we're going to receive 6 additional Lo bits.
    return Sample32(msb32(rx)) ;
}

Device::Mcp3008::Circuit::Sample
Device::Mcp3008::Spi0::Sample32::fetch() const
{
    // pos. 7-16
    return Circuit::Sample::coset(this->i >> 15) ;
}

Device::Mcp3008::Spi0::Error
Device::Mcp3008::Spi0::Sample32::verify() const
{
    Error error ;
    // 7-bit head
    error.head = 0 != (0xfe000000 & (this->i ^ 0xfc000000)) ;
    // 9 + 1 + 9 bit sample
    auto msb =         this->i  >> 15 ; // pos.  7-16
    auto lsb = reverse(this->i) >> 16 ; // pos. 25-16
    error.mismatch = 0 != (0x3ff & (msb ^ lsb)) ;
    // 6-bit tail
    error.tail = 0 != (0x3f & this->i) ;
    return error ;
}

<commit_msg>cosmetic change<commit_after>// BSD 2-Clause License, see github.com/ma16/rpio

#include "Spi0.h"
#include <vector>

static uint32_t msb32(uint8_t const *p)
{
    uint32_t i = p[0] ;
    i <<= 8 ; i |= p[1] ;
    i <<= 8 ; i |= p[2] ;
    i <<= 8 ; i |= p[3] ;
    return i ;
}

static uint32_t reverse(uint32_t i)
{
    i = (i & 0xffff0000) >> 16 | (i & 0x0000ffff) << 16 ;
    i = (i & 0xff00ff00) >>  8 | (i & 0x00ff00ff) <<  8 ;
    i = (i & 0xf0f0f0f0) >>  4 | (i & 0x0f0f0f0f) <<  4 ;
    i = (i & 0xcccccccc) >>  2 | (i & 0x33333333) <<  2 ;
    i = (i & 0xaaaaaaaa) >>  1 | (i & 0x55555555) <<  1 ;
    return i ;
}

Device::Mcp3008::Spi0::Sample24
Device::Mcp3008::Spi0::query24(Circuit::Source source)
{
    // 17-bit dialog
    uint8_t tx[4] = {0} ; // MOSI: 1 + SOURCE:4 + ANY:12 (+ANY:7)
    tx[0] = static_cast<uint8_t>(0x80 | (source.value() << 3)) ;
    uint8_t rx[4] ; // MISO: Hi:6 + Lo:1 + MSB:10 (+Lo:7)
    this->spi.transceive(3,tx,rx) ;
    // SPI0 transfers are a multiple of 8-bit. Thus, 17 bits become
    // 24 bits and so we're going to receive also 7 LSB bits of the
    // sample. We use 32-bit buffers (instead of 24-bit) because of
    // the msb32() function.
    return Sample24(msb32(rx)) ;
}

Device::Mcp3008::Circuit::Sample
Device::Mcp3008::Spi0::Sample24::fetch() const
{
    // pos. 7-16
    return Circuit::Sample::coset(this->i >> 15) ;
}

Device::Mcp3008::Spi0::Error
Device::Mcp3008::Spi0::Sample24::verify() const
{
    Error error ;
    // 7-bit head
    error.head = 0 != (0xfe000000 & (this->i ^ 0xfc000000)) ;
    auto msb =         this->i  >> 15 ; // pos.  7-16
    auto lsb = reverse(this->i) >> 16 ; // pos. 25-16
    // 9 + 1 + 7 bit sample
    error.mismatch = 0 != (0xff & (msb ^ lsb)) ;
    error.tail = 0 ;
    return error ;
}

Device::Mcp3008::Spi0::Sample32
Device::Mcp3008::Spi0::query32(Circuit::Source source)
{
    // 26-bit dialog
    uint8_t tx[4] = {0} ; // MOSI: 1 + SOURCE:4 + ANY:21 (+ANY:6)
    tx[0] = static_cast<uint8_t>(0x80 | (source.value() << 3)) ;
    uint8_t rx[4] ; // MISO: Hi:6 + Lo:1 + MSB:10 + LSB:9 (+Lo:6)
    this->spi.transceive(4,tx,rx) ;
    // SPI0 transfers are a multiple of 8-bit. Thus, 26 bits become
    // 32 bits and so we're going to receive 6 additional Lo bits.
    return Sample32(msb32(rx)) ;
}

Device::Mcp3008::Circuit::Sample
Device::Mcp3008::Spi0::Sample32::fetch() const
{
    // pos. 7-16
    return Circuit::Sample::coset(this->i >> 15) ;
}

Device::Mcp3008::Spi0::Error
Device::Mcp3008::Spi0::Sample32::verify() const
{
    Error error ;
    // 7-bit head
    error.head = 0 != (0xfe000000 & (this->i ^ 0xfc000000)) ;
    // 9 + 1 + 9 bit sample
    auto msb =         this->i  >> 15 ; // pos.  7-16
    auto lsb = reverse(this->i) >> 16 ; // pos. 25-16
    error.mismatch = 0 != (0x3ff & (msb ^ lsb)) ;
    // 6-bit tail
    error.tail = 0 != (0x3f & this->i) ;
    return error ;
}

<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////////
// DownloadUI
///////////////////////////////////////////////////////////////////////////////////

#include "Framework.hpp"

#include "../core/jni_helper.hpp"

extern "C"
{
  class IndexBinding
  {
  private:
    shared_ptr<jobject> m_self;

    jfieldID m_groupID;
    jfieldID m_countryID;
    jfieldID m_regionID;

    jobject object() const { return *m_self.get(); }

  public:
    IndexBinding(jobject self) : m_self(jni::make_global_ref(self))
    {
      jclass klass = jni::GetEnv()->GetObjectClass(object());

      m_groupID = jni::GetEnv()->GetFieldID(klass, "mGroup", "I");
      m_countryID = jni::GetEnv()->GetFieldID(klass, "mCountry", "I");
      m_regionID = jni::GetEnv()->GetFieldID(klass, "mRegion", "I");
    }

    int group() const
    {
      return jni::GetEnv()->GetIntField(object(), m_groupID);
    }

    int country() const
    {
      return jni::GetEnv()->GetIntField(object(), m_countryID);
    }

    int region() const
    {
      return jni::GetEnv()->GetIntField(object(), m_regionID);
    }

    storage::TIndex const toNative() const
    {
      return storage::TIndex(group(), country(), region());
    }

    static jobject toJava(storage::TIndex const & idx)
    {
      JNIEnv * env = jni::GetEnv();

      jclass klass = env->FindClass("com/mapswithme/maps/MapStorage$Index");
      ASSERT(klass, ());

      jint group = idx.m_group;
      jint country = idx.m_country;
      jint region = idx.m_region;

      jmethodID methodId = env->GetMethodID(klass, "<init>", "(III)V");
      ASSERT(methodId, ());

      return env->NewObject(klass, methodId, group, country, region);
    }
  };

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_MapStorage_countriesCount(JNIEnv * env, jobject thiz, jobject idx)
  {
    return static_cast<jint>(g_framework->Storage().CountriesCount(IndexBinding(idx).toNative()));
  }

  JNIEXPORT jstring JNICALL
  Java_com_mapswithme_maps_MapStorage_countryName(JNIEnv * env, jobject thiz, jobject idx)
  {
    string const name = g_framework->Storage().CountryName(IndexBinding(idx).toNative());
    return env->NewStringUTF(name.c_str());
  }

  JNIEXPORT jstring JNICALL
  Java_com_mapswithme_maps_MapStorage_countryFlag(JNIEnv * env, jobject thiz, jobject idx)
  {
    string const name = g_framework->Storage().CountryFlag(IndexBinding(idx).toNative());
    return env->NewStringUTF(name.c_str());
  }

  JNIEXPORT jlong JNICALL
  Java_com_mapswithme_maps_MapStorage_countryLocalSizeInBytes(JNIEnv * env, jobject thiz, jobject idx)
  {
    return g_framework->Storage().CountrySizeInBytes(IndexBinding(idx).toNative()).first;
  }

  JNIEXPORT jlong JNICALL
  Java_com_mapswithme_maps_MapStorage_countryRemoteSizeInBytes(JNIEnv * env, jobject thiz, jobject idx)
  {
    return g_framework->Storage().CountrySizeInBytes(IndexBinding(idx).toNative()).second;
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_MapStorage_countryStatus(JNIEnv * env, jobject thiz, jobject idx)
  {
    return static_cast<jint>(g_framework->Storage().CountryStatus(IndexBinding(idx).toNative()));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_MapStorage_downloadCountry(JNIEnv * env, jobject thiz, jobject idx)
  {
    g_framework->Storage().DownloadCountry(IndexBinding(idx).toNative());
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_MapStorage_deleteCountry(JNIEnv * env, jobject thiz, jobject idx)
  {
    g_framework->Storage().DeleteCountry(IndexBinding(idx).toNative());
  }

  JNIEXPORT jobject JNICALL
  Java_com_mapswithme_maps_MapStorage_findIndexByName(JNIEnv * env, jobject thiz, jstring name)
  {
    char const * strCountry = env->GetStringUTFChars(name, 0);

    if (!strCountry)
      return IndexBinding::toJava(storage::TIndex());

    return IndexBinding::toJava(g_framework->Storage().FindIndexByName(strCountry));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_MapStorage_showCountry(JNIEnv * env, jobject thiz, jobject idx)
  {
    m2::RectD const rect = g_framework->Storage().CountryBounds(IndexBinding(idx).toNative());
    g_framework->ShowCountry(rect);
  }

  void ReportChangeCountryStatus(shared_ptr<jobject> const & obj, storage::TIndex const & idx)
  {
    JNIEnv * env = jni::GetEnv();

    jmethodID methodID = jni::GetJavaMethodID(env, *obj.get(), "onCountryStatusChanged", "(Lcom/mapswithme/maps/MapStorage$Index;)V");
    env->CallVoidMethod(*obj.get(), methodID, IndexBinding::toJava(idx));
  }

  void ReportCountryProgress(shared_ptr<jobject> const & obj, storage::TIndex const & idx, pair<int64_t, int64_t> const & p)
  {
    jlong const current = p.first;
    jlong const total = p.second;

    JNIEnv * env = jni::GetEnv();

    jmethodID methodID = jni::GetJavaMethodID(env, *obj.get(), "onCountryProgress", "(Lcom/mapswithme/maps/MapStorage$Index;JJ)V");
    env->CallVoidMethod(*obj.get(), methodID, IndexBinding::toJava(idx), current, total);
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_MapStorage_subscribe(JNIEnv * env, jobject thiz, jobject obj)
  {
    LOG(LDEBUG, ("Subscribe on storage"));

    return g_framework->Storage().Subscribe(bind(&ReportChangeCountryStatus, jni::make_global_ref(obj), _1),
                                            bind(&ReportCountryProgress, jni::make_global_ref(obj), _1, _2));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_MapStorage_unsubscribe(JNIEnv * env, jobject thiz, jint slotID)
  {
    LOG(LDEBUG, ("UnSubscribe from storage"));

    g_framework->Storage().Unsubscribe(slotID);
  }
}
<commit_msg>Minor changes.<commit_after>///////////////////////////////////////////////////////////////////////////////////
// DownloadUI
///////////////////////////////////////////////////////////////////////////////////

#include "Framework.hpp"

#include "../core/jni_helper.hpp"

extern "C"
{
  class IndexBinding
  {
  private:
    shared_ptr<jobject> m_self;

    jfieldID m_groupID;
    jfieldID m_countryID;
    jfieldID m_regionID;

    jobject object() const { return *m_self.get(); }

  public:
    IndexBinding(jobject self) : m_self(jni::make_global_ref(self))
    {
      jclass klass = jni::GetEnv()->GetObjectClass(object());

      m_groupID = jni::GetEnv()->GetFieldID(klass, "mGroup", "I");
      m_countryID = jni::GetEnv()->GetFieldID(klass, "mCountry", "I");
      m_regionID = jni::GetEnv()->GetFieldID(klass, "mRegion", "I");
    }

    int group() const
    {
      return jni::GetEnv()->GetIntField(object(), m_groupID);
    }

    int country() const
    {
      return jni::GetEnv()->GetIntField(object(), m_countryID);
    }

    int region() const
    {
      return jni::GetEnv()->GetIntField(object(), m_regionID);
    }

    storage::TIndex const toNative() const
    {
      return storage::TIndex(group(), country(), region());
    }

    static jobject toJava(storage::TIndex const & idx)
    {
      JNIEnv * env = jni::GetEnv();

      jclass klass = env->FindClass("com/mapswithme/maps/MapStorage$Index");
      ASSERT(klass, ());

      jmethodID methodID = env->GetMethodID(klass, "<init>", "(III)V")
      ASSERT(methodId, ());

      return env->NewObject(klass, methodID,
                            (jint)idx.m_group, (jint)idx.m_country, (jint)idx.m_region);
    }
  };

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_MapStorage_countriesCount(JNIEnv * env, jobject thiz, jobject idx)
  {
    return static_cast<jint>(g_framework->Storage().CountriesCount(IndexBinding(idx).toNative()));
  }

  JNIEXPORT jstring JNICALL
  Java_com_mapswithme_maps_MapStorage_countryName(JNIEnv * env, jobject thiz, jobject idx)
  {
    string const name = g_framework->Storage().CountryName(IndexBinding(idx).toNative());
    return env->NewStringUTF(name.c_str());
  }

  JNIEXPORT jstring JNICALL
  Java_com_mapswithme_maps_MapStorage_countryFlag(JNIEnv * env, jobject thiz, jobject idx)
  {
    string const name = g_framework->Storage().CountryFlag(IndexBinding(idx).toNative());
    return env->NewStringUTF(name.c_str());
  }

  JNIEXPORT jlong JNICALL
  Java_com_mapswithme_maps_MapStorage_countryLocalSizeInBytes(JNIEnv * env, jobject thiz, jobject idx)
  {
    return g_framework->Storage().CountrySizeInBytes(IndexBinding(idx).toNative()).first;
  }

  JNIEXPORT jlong JNICALL
  Java_com_mapswithme_maps_MapStorage_countryRemoteSizeInBytes(JNIEnv * env, jobject thiz, jobject idx)
  {
    return g_framework->Storage().CountrySizeInBytes(IndexBinding(idx).toNative()).second;
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_MapStorage_countryStatus(JNIEnv * env, jobject thiz, jobject idx)
  {
    return static_cast<jint>(g_framework->Storage().CountryStatus(IndexBinding(idx).toNative()));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_MapStorage_downloadCountry(JNIEnv * env, jobject thiz, jobject idx)
  {
    g_framework->Storage().DownloadCountry(IndexBinding(idx).toNative());
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_MapStorage_deleteCountry(JNIEnv * env, jobject thiz, jobject idx)
  {
    g_framework->Storage().DeleteCountry(IndexBinding(idx).toNative());
  }

  JNIEXPORT jobject JNICALL
  Java_com_mapswithme_maps_MapStorage_findIndexByName(JNIEnv * env, jobject thiz, jstring name)
  {
    char const * strCountry = env->GetStringUTFChars(name, 0);

    if (!strCountry)
      return IndexBinding::toJava(storage::TIndex());

    return IndexBinding::toJava(g_framework->Storage().FindIndexByName(strCountry));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_MapStorage_showCountry(JNIEnv * env, jobject thiz, jobject idx)
  {
    m2::RectD const rect = g_framework->Storage().CountryBounds(IndexBinding(idx).toNative());
    g_framework->ShowCountry(rect);
  }

  void ReportChangeCountryStatus(shared_ptr<jobject> const & obj, storage::TIndex const & idx)
  {
    JNIEnv * env = jni::GetEnv();

    jmethodID methodID = jni::GetJavaMethodID(env, *obj.get(), "onCountryStatusChanged", "(Lcom/mapswithme/maps/MapStorage$Index;)V");
    env->CallVoidMethod(*obj.get(), methodID, IndexBinding::toJava(idx));
  }

  void ReportCountryProgress(shared_ptr<jobject> const & obj, storage::TIndex const & idx, pair<int64_t, int64_t> const & p)
  {
    jlong const current = p.first;
    jlong const total = p.second;

    JNIEnv * env = jni::GetEnv();

    jmethodID methodID = jni::GetJavaMethodID(env, *obj.get(), "onCountryProgress", "(Lcom/mapswithme/maps/MapStorage$Index;JJ)V");
    env->CallVoidMethod(*obj.get(), methodID, IndexBinding::toJava(idx), current, total);
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_MapStorage_subscribe(JNIEnv * env, jobject thiz, jobject obj)
  {
    LOG(LDEBUG, ("Subscribe on storage"));

    return g_framework->Storage().Subscribe(bind(&ReportChangeCountryStatus, jni::make_global_ref(obj), _1),
                                            bind(&ReportCountryProgress, jni::make_global_ref(obj), _1, _2));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_MapStorage_unsubscribe(JNIEnv * env, jobject thiz, jint slotID)
  {
    LOG(LDEBUG, ("UnSubscribe from storage"));

    g_framework->Storage().Unsubscribe(slotID);
  }
}
<|endoftext|>


<commit_before>// @(#)root/g3d:$Id$
// Author: Valery Fine(fine@mail.cern.ch)   04/05/99

// @(#)root/g3d:$Id$
// Author: Valery Fine(fine@mail.cern.ch)   24/04/99

#include "TPoints3DABC.h"
#include "TMath.h"

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TPoints3DABC                                                         //
//                                                                      //
// Abstract class to define Arrays of 3D points                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

ClassImp(TPoints3DABC)

//______________________________________________________________________________
Int_t TPoints3DABC::Add(Float_t x, Float_t y, Float_t z)
{
   // Add one 3D point defined by x,y,z to the array of the points
   // as its last element

   return AddLast(x,y,z);
}

//______________________________________________________________________________
Int_t TPoints3DABC::AddLast(Float_t x, Float_t y, Float_t z)
{
   // Add one 3D point defined by x,y,z to the array of the points
   // as its last element

   return SetNextPoint(x,y,z);
}

//______________________________________________________________________________
Int_t TPoints3DABC::DistancetoLine(Int_t px, Int_t py, Float_t x1, Float_t y1, Float_t x2, Float_t y2, Int_t lineWidth )
{
   // Compute distance from point px,py to an axis of the band defined.
   //  by pair points  (x1,y1),(x2,y2) where lineWidth is the width of the band
   //
   //  Compute the closest distance of approach from point px,py to this line.
   //  The distance is computed in pixels units.
   //
   //
   //  Algorithm:
   //
   //    A(x1,y1)         P                             B(x2,y2)
   //    ------------------------------------------------
   //                     I
   //                     I
   //                     I
   //                     I
   //                    M(x,y)
   //
   //  Let us call  a = distance AM     a2=a**2
   //               b = distance BM     b2=b**2
   //               c = distance AB     c2=c**2
   //               d = distance PM     d2=d**2
   //               u = distance AP     u2=u**2
   //               v = distance BP     v2=v**2     c = u + v
   //
   //  d2 = a2 - u2
   //  d2 = b2 - v2  = b2 -(c-u)**2
   //     ==> u = (a2 -b2 +c2)/2c
   //
   //   Float_t x1    = gPad->XtoAbsPixel(xp1);
   //   Float_t y1    = gPad->YtoAbsPixel(yp1);
   //   Float_t x2    = gPad->XtoAbsPixel(xp2);
   //   Float_t y2    = gPad->YtoAbsPixel(yp2);

   Float_t xl, xt, yl, yt;
   Float_t x     = px;
   Float_t y     = py;
   if (x1 < x2) {xl = x1; xt = x2;}
   else         {xl = x2; xt = x1;}
   if (y1 < y2) {yl = y1; yt = y2;}
   else         {yl = y2; yt = y1;}
   if (x < xl-2 || x> xt+2) return 9999;  //following algorithm only valid in the box
   if (y < yl-2 || y> yt+2) return 9999;  //surrounding the line
   Float_t xx1   = x  - x1;
   Float_t xx2   = x  - x2;
   Float_t x1x2  = x1 - x2;
   Float_t yy1   = y  - y1;
   Float_t yy2   = y  - y2;
   Float_t y1y2  = y1 - y2;
   Float_t a2    = xx1*xx1   + yy1*yy1;
   Float_t b2    = xx2*xx2   + yy2*yy2;
   Float_t c2    = x1x2*x1x2 + y1y2*y1y2;
   if (c2 <= 0)  return 9999;
   Float_t c     = TMath::Sqrt(c2);
   Float_t u     = (a2 - b2 + c2)/(2*c);
   Float_t d2    = TMath::Abs(a2 - u*u);
   if (d2 < 0)   return 9999;

   return Int_t(TMath::Sqrt(d2) - 0.5*float(lineWidth));
}

//______________________________________________________________________________
Int_t TPoints3DABC::SetNextPoint(Float_t x, Float_t y, Float_t z)
{
   // Add one 3D point defined by x,y,z to the array of the points
   // as its last element

   return SetPoint(GetLastPosition()+1,x,y,z);
}

//______________________________________________________________________________
Int_t TPoints3DABC::GetN() const
{
   // GetN()  returns the number of allocated cells if any.
   //         GetN() > 0 shows how many cells
   //         can be available via GetP() method.
   //         GetN() == 0 then GetP() must return 0 as well

   return 0;
}

//______________________________________________________________________________
Float_t *TPoints3DABC::GetP() const
{
   // GetP()  returns the pointer to the float point array
   //         of points if available
   //         The number of the available celss can be found via
   //         GetN() method.
   //         GetN() > 0 shows how many cells

   return 0;
}

//______________________________________________________________________________
Float_t *TPoints3DABC::GetXYZ(Float_t *xyz,Int_t idx,Int_t num)  const
{
   // GetXYZ(Float_t *xyz,Int_t idx,Int_t num=1) fills the buffer supplied
   // by the calling code with the points information.
   //
   //  Input parameters:
   //
   //   Float_t *xyz - an external user supplied floating point array.
   //   Int_t    num - the total number of the points to be copied
   //                  the dimension of that array the size of the
   //                  array is num*sizeof(Float_t) at least
   //   Int_t    idx - The index of the first copy to be taken.
   //
   //  Return: The pointer to the buffer array supplied

   if (xyz) {
      Int_t size = TMath::Min(idx+num,Size());
      Int_t j=0;
      for (Int_t i=idx;i<size;i++) {
         xyz[j++] = GetX(i);
         xyz[j++] = GetY(i);
         xyz[j++] = GetZ(i);
      }
   }
   return xyz;
}
<commit_msg>- class header.<commit_after>// @(#)root/g3d:$Id$
// Author: Valery Fine(fine@mail.cern.ch)   04/05/99

// @(#)root/g3d:$Id$
// Author: Valery Fine(fine@mail.cern.ch)   24/04/99

#include "TPoints3DABC.h"
#include "TMath.h"

ClassImp(TPoints3DABC)

//______________________________________________________________________________
/* Begin_Html

The TPoints3DABC class

Abstract class to define Arrays of 3D points.
End_Html */

//______________________________________________________________________________
Int_t TPoints3DABC::Add(Float_t x, Float_t y, Float_t z)
{
   // Add one 3D point defined by x,y,z to the array of the points
   // as its last element

   return AddLast(x,y,z);
}

//______________________________________________________________________________
Int_t TPoints3DABC::AddLast(Float_t x, Float_t y, Float_t z)
{
   // Add one 3D point defined by x,y,z to the array of the points
   // as its last element

   return SetNextPoint(x,y,z);
}

//______________________________________________________________________________
Int_t TPoints3DABC::DistancetoLine(Int_t px, Int_t py, Float_t x1, Float_t y1, Float_t x2, Float_t y2, Int_t lineWidth )
{
   // Compute distance from point px,py to an axis of the band defined.
   //  by pair points  (x1,y1),(x2,y2) where lineWidth is the width of the band
   //
   //  Compute the closest distance of approach from point px,py to this line.
   //  The distance is computed in pixels units.
   //
   //
   //  Algorithm:
   //
   //    A(x1,y1)         P                             B(x2,y2)
   //    ------------------------------------------------
   //                     I
   //                     I
   //                     I
   //                     I
   //                    M(x,y)
   //
   //  Let us call  a = distance AM     a2=a**2
   //               b = distance BM     b2=b**2
   //               c = distance AB     c2=c**2
   //               d = distance PM     d2=d**2
   //               u = distance AP     u2=u**2
   //               v = distance BP     v2=v**2     c = u + v
   //
   //  d2 = a2 - u2
   //  d2 = b2 - v2  = b2 -(c-u)**2
   //     ==> u = (a2 -b2 +c2)/2c
   //
   //   Float_t x1    = gPad->XtoAbsPixel(xp1);
   //   Float_t y1    = gPad->YtoAbsPixel(yp1);
   //   Float_t x2    = gPad->XtoAbsPixel(xp2);
   //   Float_t y2    = gPad->YtoAbsPixel(yp2);

   Float_t xl, xt, yl, yt;
   Float_t x     = px;
   Float_t y     = py;
   if (x1 < x2) {xl = x1; xt = x2;}
   else         {xl = x2; xt = x1;}
   if (y1 < y2) {yl = y1; yt = y2;}
   else         {yl = y2; yt = y1;}
   if (x < xl-2 || x> xt+2) return 9999;  //following algorithm only valid in the box
   if (y < yl-2 || y> yt+2) return 9999;  //surrounding the line
   Float_t xx1   = x  - x1;
   Float_t xx2   = x  - x2;
   Float_t x1x2  = x1 - x2;
   Float_t yy1   = y  - y1;
   Float_t yy2   = y  - y2;
   Float_t y1y2  = y1 - y2;
   Float_t a2    = xx1*xx1   + yy1*yy1;
   Float_t b2    = xx2*xx2   + yy2*yy2;
   Float_t c2    = x1x2*x1x2 + y1y2*y1y2;
   if (c2 <= 0)  return 9999;
   Float_t c     = TMath::Sqrt(c2);
   Float_t u     = (a2 - b2 + c2)/(2*c);
   Float_t d2    = TMath::Abs(a2 - u*u);
   if (d2 < 0)   return 9999;

   return Int_t(TMath::Sqrt(d2) - 0.5*float(lineWidth));
}

//______________________________________________________________________________
Int_t TPoints3DABC::SetNextPoint(Float_t x, Float_t y, Float_t z)
{
   // Add one 3D point defined by x,y,z to the array of the points
   // as its last element

   return SetPoint(GetLastPosition()+1,x,y,z);
}

//______________________________________________________________________________
Int_t TPoints3DABC::GetN() const
{
   // GetN()  returns the number of allocated cells if any.
   //         GetN() > 0 shows how many cells
   //         can be available via GetP() method.
   //         GetN() == 0 then GetP() must return 0 as well

   return 0;
}

//______________________________________________________________________________
Float_t *TPoints3DABC::GetP() const
{
   // GetP()  returns the pointer to the float point array
   //         of points if available
   //         The number of the available celss can be found via
   //         GetN() method.
   //         GetN() > 0 shows how many cells

   return 0;
}

//______________________________________________________________________________
Float_t *TPoints3DABC::GetXYZ(Float_t *xyz,Int_t idx,Int_t num)  const
{
   // GetXYZ(Float_t *xyz,Int_t idx,Int_t num=1) fills the buffer supplied
   // by the calling code with the points information.
   //
   //  Input parameters:
   //
   //   Float_t *xyz - an external user supplied floating point array.
   //   Int_t    num - the total number of the points to be copied
   //                  the dimension of that array the size of the
   //                  array is num*sizeof(Float_t) at least
   //   Int_t    idx - The index of the first copy to be taken.
   //
   //  Return: The pointer to the buffer array supplied

   if (xyz) {
      Int_t size = TMath::Min(idx+num,Size());
      Int_t j=0;
      for (Int_t i=idx;i<size;i++) {
         xyz[j++] = GetX(i);
         xyz[j++] = GetY(i);
         xyz[j++] = GetZ(i);
      }
   }
   return xyz;
}
<|endoftext|>