<commit_before>#include <ctime>
#include <iomanip>
#include <iostream>
#include <chrono>
#include <cstdint>
#include <tuple>
#include <utility>
#include <queue>

#define cimg_display 0
#include "CImg.h"
using namespace cimg_library;

#include "Buddha.h"

rgb ColorGrayscale::color(uint64_t count, uint64_t max) const {
    unsigned char v = count / (double)max * 256.;
    return rgb({ v, v, v });
}

rgb ColorSqrt::color(uint64_t count, uint64_t max) const {
    unsigned char v = 256. * std::sqrt(count) / std::sqrt(max);
    return rgb({ v, v, v });
}

rgb ColorGrayscaleSqrtMixed::color(uint64_t count, uint64_t max) const {
    unsigned char v1 = count / (double)max * 256.;
    unsigned char v2 = 256. * std::sqrt(count) / std::sqrt(max);
    return rgb({ v1, v2, 0 });
}

std::string Buddha::log_priority_name(LogPriority p) const {
    switch (p) {
        case LogPriority::ERROR: return "ERROR";
        case LogPriority::WARNING: return "WARNING";
        case LogPriority::NOTICE: return "NOTICE";
        case LogPriority::INFO: return "INFO";
        case LogPriority::DEBUG: return "DEBUG";
    }

    return "UNKNOWN";
}

Buddha::Buddha(const Params & p, const std::size_t thread_vector_size)
  : thread_vector_size_(thread_vector_size) {
    x_size_ = p.width;
    y_size_ = p.width;
    radius_ = p.radius;
    max_iterations_ = p.max_iterations;
    min_iterations_ = p.min_iterations;
    subpixel_resolution_ = p.subpixel_resolution;
    filename_ = p.name + "." + p.format;
    schema = p.schema != nullptr
        ? p.schema
        : new ColorGrayscale;
    num_threads_ = p.num_threads > 0
        ? p.num_threads
        : std::thread::hardware_concurrency();

    if (max_iterations_ > thread_vector_size)
        throw MaxIterationsTooBigException();

    if (min_iterations_ > max_iterations_)
        throw MinGreaterThanMaxException();

    data_ = std::vector<uint64_t>(x_size_ * y_size_);
}

Buddha::Params Buddha::get_empty_params() {
    Params p;
    p.num_threads = -1;
    p.schema = nullptr;
    return p;
}

void Buddha::run() {
    uint64_t part_size = x_size_ * y_size_ / num_threads_;

    std::thread logger(&Buddha::log_printer, this);
    logger.detach();

    log(LogPriority::NOTICE, "Rendering " + filename_);

    for (std::size_t i = 0; i < num_threads_; ++i)
        threads_.emplace_back(&Buddha::worker, this, i * part_size, (i+1) * part_size);

    for (auto & t : threads_)
        t.join();

    log(LogPriority::NOTICE, "Rendering " + filename_ + " done");

    auto img = render();
    img.save(filename_.c_str());
}

void Buddha::log_printer() {
    std::size_t counter = 0;
    double all = x_size_ * y_size_ * subpixel_resolution_ * subpixel_resolution_;

    while (++counter) {
        if (counter % 10 == 0) {
            log(LogPriority::NOTICE,
                "Done " + std::to_string(100. * progress_ / all) + "%");
        }

        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        std::lock_guard<std::mutex> _(logitems_lock_);

        if (logitems_.empty())
            continue;

        while (!logitems_.empty()) {
            auto item = logitems_.front();
            logitems_.pop();

            auto& out = std::get<1>(item) == LogPriority::ERROR ? std::cerr : std::cout;
            std::time_t ttp = std::chrono::system_clock::to_time_t(std::get<0>(item));
            struct tm *tm_now = localtime(&ttp);
            std::string time = std::asctime(tm_now);

            out << log_priority_name(std::get<1>(item)) << " "
                << time.substr(0, time.size() - 1) << "     "
                << std::get<2>(item) << std::endl;
        }
    }
}

void Buddha::log(LogPriority p, std::string msg) {
    std::lock_guard<std::mutex> _(logitems_lock_);
    logitems_.push(std::make_tuple(std::chrono::system_clock::now(), p, msg));
}

std::pair<uint64_t, uint64_t> Buddha::lin2car(uint64_t pos) const {
    return std::make_pair(pos % x_size_, pos / x_size_);
}

uint64_t Buddha::car2lin(uint64_t x, uint64_t y) const {
    return y * x_size_ + x;
}

Buddha::complex_type Buddha::car2complex(uint64_t x, uint64_t y) const {
    floating_type re = radius_ * ( 2. / x_size_ * x - 1);
    floating_type im = radius_ * ( 2. / y_size_ * y - 1);
    return complex_type(re, im);
}

std::pair<uint64_t, uint64_t> Buddha::complex2car(
    Buddha::complex_type c) const {
    uint64_t x = (uint64_t)(x_size_ * (c.real() / radius_ + 1) / 2.);
    uint64_t y = (uint64_t)(y_size_ * (c.imag() / radius_ + 1) / 2.);
    return std::make_pair(x, y);
}

Buddha::complex_type Buddha::lin2complex(uint64_t pos) const {
   auto pair = lin2car(pos);
   return car2complex(pair.first, pair.second);
}

uint64_t Buddha::complex2lin(Buddha::complex_type c) const {
    auto pair = complex2car(c);
    return car2lin(pair.first, pair.second);
}

CImg<unsigned char> Buddha::render() {
    std::lock_guard<std::mutex> _(data_lock_);
    CImg<unsigned char> img(x_size_, y_size_, 1, 3, 0);

    uint64_t max = 0;
    for (uint64_t i = 0; i < data_.size(); ++i)
        if (max < data_[i])
            max = data_[i];

    for (uint64_t i = 0; i < data_.size() / 2; ++i) {
        auto car = lin2car(i);
        rgb c = schema->color(data_[i], max);
        unsigned char color[] = { c.r, c.g, c.b };
        img.draw_point(car.first, car.second, color);
        img.draw_point(car.first, y_size_ - car.second - 1, color);
    }

    return img;
}

bool Buddha::mandelbrot_hint(complex_type z) const {
    complex_type unit(1, 0), four(4, 0);
    if (std::abs(unit - std::sqrt(unit - four*z)) < 1) return true;
    if (z.real() * z.real() + z.imag() * z.imag() <= 0.25) return true;
    return false;
}
<commit_msg>another mandelbrot hint<commit_after>#include <ctime>
#include <iomanip>
#include <iostream>
#include <chrono>
#include <cstdint>
#include <tuple>
#include <utility>
#include <queue>

#define cimg_display 0
#include "CImg.h"
using namespace cimg_library;

#include "Buddha.h"

rgb ColorGrayscale::color(uint64_t count, uint64_t max) const {
    unsigned char v = count / (double)max * 256.;
    return rgb({ v, v, v });
}

rgb ColorSqrt::color(uint64_t count, uint64_t max) const {
    unsigned char v = 256. * std::sqrt(count) / std::sqrt(max);
    return rgb({ v, v, v });
}

rgb ColorGrayscaleSqrtMixed::color(uint64_t count, uint64_t max) const {
    unsigned char v1 = count / (double)max * 256.;
    unsigned char v2 = 256. * std::sqrt(count) / std::sqrt(max);
    return rgb({ v1, v2, 0 });
}

std::string Buddha::log_priority_name(LogPriority p) const {
    switch (p) {
        case LogPriority::ERROR: return "ERROR";
        case LogPriority::WARNING: return "WARNING";
        case LogPriority::NOTICE: return "NOTICE";
        case LogPriority::INFO: return "INFO";
        case LogPriority::DEBUG: return "DEBUG";
    }

    return "UNKNOWN";
}

Buddha::Buddha(const Params & p, const std::size_t thread_vector_size)
  : thread_vector_size_(thread_vector_size) {
    x_size_ = p.width;
    y_size_ = p.width;
    radius_ = p.radius;
    max_iterations_ = p.max_iterations;
    min_iterations_ = p.min_iterations;
    subpixel_resolution_ = p.subpixel_resolution;
    filename_ = p.name + "." + p.format;
    schema = p.schema != nullptr
        ? p.schema
        : new ColorGrayscale;
    num_threads_ = p.num_threads > 0
        ? p.num_threads
        : std::thread::hardware_concurrency();

    if (max_iterations_ > thread_vector_size)
        throw MaxIterationsTooBigException();

    if (min_iterations_ > max_iterations_)
        throw MinGreaterThanMaxException();

    data_ = std::vector<uint64_t>(x_size_ * y_size_);
}

Buddha::Params Buddha::get_empty_params() {
    Params p;
    p.num_threads = -1;
    p.schema = nullptr;
    return p;
}

void Buddha::run() {
    uint64_t part_size = x_size_ * y_size_ / num_threads_;

    std::thread logger(&Buddha::log_printer, this);
    logger.detach();

    log(LogPriority::NOTICE, "Rendering " + filename_);

    for (std::size_t i = 0; i < num_threads_; ++i)
        threads_.emplace_back(&Buddha::worker, this, i * part_size, (i+1) * part_size);

    for (auto & t : threads_)
        t.join();

    log(LogPriority::NOTICE, "Rendering " + filename_ + " done");

    auto img = render();
    img.save(filename_.c_str());
}

void Buddha::log_printer() {
    std::size_t counter = 0;
    double all = x_size_ * y_size_ * subpixel_resolution_ * subpixel_resolution_;

    while (++counter) {
        if (counter % 10 == 0) {
            log(LogPriority::NOTICE,
                "Done " + std::to_string(100. * progress_ / all) + "%");
        }

        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        std::lock_guard<std::mutex> _(logitems_lock_);

        if (logitems_.empty())
            continue;

        while (!logitems_.empty()) {
            auto item = logitems_.front();
            logitems_.pop();

            auto& out = std::get<1>(item) == LogPriority::ERROR ? std::cerr : std::cout;
            std::time_t ttp = std::chrono::system_clock::to_time_t(std::get<0>(item));
            struct tm *tm_now = localtime(&ttp);
            std::string time = std::asctime(tm_now);

            out << log_priority_name(std::get<1>(item)) << " "
                << time.substr(0, time.size() - 1) << "     "
                << std::get<2>(item) << std::endl;
        }
    }
}

void Buddha::log(LogPriority p, std::string msg) {
    std::lock_guard<std::mutex> _(logitems_lock_);
    logitems_.push(std::make_tuple(std::chrono::system_clock::now(), p, msg));
}

std::pair<uint64_t, uint64_t> Buddha::lin2car(uint64_t pos) const {
    return std::make_pair(pos % x_size_, pos / x_size_);
}

uint64_t Buddha::car2lin(uint64_t x, uint64_t y) const {
    return y * x_size_ + x;
}

Buddha::complex_type Buddha::car2complex(uint64_t x, uint64_t y) const {
    floating_type re = radius_ * ( 2. / x_size_ * x - 1);
    floating_type im = radius_ * ( 2. / y_size_ * y - 1);
    return complex_type(re, im);
}

std::pair<uint64_t, uint64_t> Buddha::complex2car(
    Buddha::complex_type c) const {
    uint64_t x = (uint64_t)(x_size_ * (c.real() / radius_ + 1) / 2.);
    uint64_t y = (uint64_t)(y_size_ * (c.imag() / radius_ + 1) / 2.);
    return std::make_pair(x, y);
}

Buddha::complex_type Buddha::lin2complex(uint64_t pos) const {
   auto pair = lin2car(pos);
   return car2complex(pair.first, pair.second);
}

uint64_t Buddha::complex2lin(Buddha::complex_type c) const {
    auto pair = complex2car(c);
    return car2lin(pair.first, pair.second);
}

CImg<unsigned char> Buddha::render() {
    std::lock_guard<std::mutex> _(data_lock_);
    CImg<unsigned char> img(x_size_, y_size_, 1, 3, 0);

    uint64_t max = 0;
    for (uint64_t i = 0; i < data_.size(); ++i)
        if (max < data_[i])
            max = data_[i];

    for (uint64_t i = 0; i < data_.size() / 2; ++i) {
        auto car = lin2car(i);
        rgb c = schema->color(data_[i], max);
        unsigned char color[] = { c.r, c.g, c.b };
        img.draw_point(car.first, car.second, color);
        img.draw_point(car.first, y_size_ - car.second - 1, color);
    }

    return img;
}

bool Buddha::mandelbrot_hint(complex_type z) const {
    complex_type unit(1, 0), four(4, 0);
    if (std::abs(unit - std::sqrt(unit - four*z)) < 1)
        return true;

    complex_type iunit(0, 1),  dist = z - iunit;
    if (dist.real() * dist.real() + dist.imag() * dist.imag() <= 1./8)
        return true;

    return false;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2000-2010 University of Utah and the Flux Group.
 *
 * {{{EMULAB-LICENSE
 *
 * This file is part of the Emulab network testbed software.
 *
 * This file is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 *
 * This file is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * }}}
 */

static const char rcsid[] = "$Id: parse_ptop.cc,v 1.44 2009-05-20 18:06:08 tarunp Exp $";

#include "port.h"

#include <boost/graph/adjacency_list.hpp>

#include <iostream>

#include <stdio.h>

using namespace boost;

#include "delay.h"
#include "physical.h"
#include "parser.h"

#include <string>
using namespace std;

extern name_pvertex_map pname2vertex;

#define ptop_error(s) errors++;cout << "PTOP:" << line << ": " << s << endl; exit(EXIT_FATAL)
#define ptop_error_noline(s) errors++;cout << "PTOP: " << s << endl

// Used to do late binding of subnode names to pnodes, so that we're no
// dependant on their ordering in the ptop file, which can be annoying to get
// right.
// Returns the number of errors found
int bind_ptop_subnodes(tb_pgraph &pg) {
    int errors = 0;

    // Iterate through all pnodes looking for ones that are subnodes
    pvertex_iterator vit,vendit;
    tie(vit,vendit) = vertices(pg);
    for (;vit != vendit;++vit) {
	tb_pnode *pnode = get(pvertex_pmap,*vit);
	if (!pnode->subnode_of_name.empty()) {
	    if (pname2vertex.find(pnode->subnode_of_name) ==
		    pname2vertex.end()) {
		ptop_error_noline(pnode->name << " is a subnode of a " <<
			"non-existent node, " << pnode->subnode_of_name << ".");
			continue;
		}
		pvertex parent_pv = pname2vertex[pnode->subnode_of_name];
		pnode->subnode_of = get(pvertex_pmap,parent_pv);
		pnode->subnode_of->has_subnode = true;
	}
    }

    return errors;
}

int parse_ptop(tb_pgraph &pg, tb_sgraph &sg, istream& input)
{
  int num_nodes = 0;
  int line=0,errors=0;
  char inbuf[16384];
  string_vector parsed_line;

  while (!input.eof()) {
    line++;
    input.getline(inbuf,16384);
    parsed_line = split_line(inbuf,' ');
    if (parsed_line.size() == 0) {continue;}

    string command = parsed_line[0];

    if (command == "node") {
      if (parsed_line.size() < 3) {
	ptop_error("Bad node line, too few arguments.");
      } else {
	num_nodes++;
	fstring name = parsed_line[1];
	bool isswitch = false;
	pvertex pv = add_vertex(pg);
	tb_pnode *p = new tb_pnode(name);
	put(pvertex_pmap,pv,p);

	unsigned int i;
	for (i = 2;
	     (i < parsed_line.size()) &&
	       (parsed_line[i] != "-");++i) {
	  string stype,load;
	  if (split_two(parsed_line[i],':',stype,load,"1") != 0) {
	    ptop_error("Bad node line, no load for type: " << stype << ".");
	  }
          fstring type(stype);
	  // Check to see if this is a static type
	  bool is_static = false;
	  if (type[0] == '*') {
	    is_static = true;
	    type.pop_front();
	  }
	  int iload;
	  if (load == "*") { // Allow * to mean unlimited
            // (okay, a really big number)
	    iload = 10000;
	  } else if (sscanf(load.c_str(),"%d",&iload) != 1) {
	    ptop_error("Bad node line, bad load: " << load << ".");
	    iload = 1;
	  }

	  /*
	   * Make a tb_ptype structure for this guy - or just add this node to
	   * it if it already exists
	   */
	  if (ptypes.find(type) == ptypes.end()) {
	      ptypes[type] = new tb_ptype(type);
	  }
	  ptypes[type]->add_slots(iload);
	  tb_ptype *ptype = ptypes[type];

	  if (type == "switch") {
	    isswitch = true;
	    p->is_switch = true;
	    p->types["switch"] = new tb_pnode::type_record(1,false,ptype);
	    svertex sv = add_vertex(sg);
	    tb_switch *s = new tb_switch();
	    put(svertex_pmap,sv,s);
	    s->mate = pv;
	    p->sgraph_switch = sv;
	    p->switches.insert(pv);
	  } else {
	    p->types[type] = new tb_pnode::type_record(iload,is_static,ptype);
	  }
	  p->type_list.push_back(p->types[type]);
	}
	for (i=i+1;(i<parsed_line.size()) && (parsed_line[i] != "-") ;++i) {
	  string sfeature,cost;
	  if (split_two(parsed_line[i],':',sfeature,cost,"0") != 0) {
	    ptop_error("Bad node line, no cost for feature: " <<
		       sfeature << ".");
	  }
      fstring feature(sfeature);

	  double gcost;
	  if (sscanf(cost.c_str(),"%lg",&gcost) != 1) {
	    ptop_error("Bad node line, bad cost: " << gcost << ".");
	    gcost = 0;
	  }

	  p->features.push_front(tb_node_featuredesire(feature,gcost));

	}
	/*
	 * Parse any other node options or flags
	 */
	for (i=i+1; i < parsed_line.size(); ++i) {
	    string flag,value;
	    split_two(parsed_line[i],':',flag,value,"(null)");
	    if (flag == "trivial_bw") {
		// Handle trivial bandwidth spec
		int trivial_bw;
		if (sscanf(value.c_str(),"%i",&trivial_bw) != 1) {
		    ptop_error("Bad bandwidth given for trivial_bw: " << value
			    << endl);
		    trivial_bw = 0;
		}
		p->trivial_bw = trivial_bw;
	    } else if (flag == "subnode_of") {
		// Handle subnode relationships
		if (!p->subnode_of_name.empty()) {
		    ptop_error("Can't be a subnode of two nodes");
		    continue;
		} else {
		    // Just store the name for now, we'll do late binding to
		    // an actual pnode later
		    p->subnode_of_name = value;
		}
	    } else if (flag == "unique") {
		// Means that we should never put this pnode into a ptype with
		// other pnodes
		p->unique = true;
	    } else {
		ptop_error("Bad flag given: " << flag << ".");
	    }
	}
	p->features.sort();
	pname2vertex[name] = pv;
      }
    } else if (command == "link") {
      if (parsed_line.size() < 8) {
	ptop_error("Bad link line, too few arguments.");
      }
      int num = 1;
#ifdef PENALIZE_BANDWIDTH
      float penalty;
      if (parsed_line.size() == 9) {
	if (sscanf(parsed_line[8].c_str(),"%f",&penalty) != 1) {
	  ptop_error("Bad number argument: " << parsed_line[8] << ".");
	  penalty=1.0;
	}
      }
#endif

#if 0
#ifdef FIX_PLINK_ENDPOINTS
      bool fixends;
#ifdef FIX_PLINKS_DEFAULT
      fixends = true;
#else
      fixends = false;
#endif
      if (parsed_line.size() == 10) {
	  if (parsed_line[9] == "fixends") {
	      fixends = true;
	  }
      }
#else
      if (parsed_line.size() > 9) {
	ptop_error("Bad link line, too many arguments.");
      }
#endif
#endif

      fstring name = parsed_line[1];
      string ssrc,ssrcmac;
      split_two(parsed_line[2],':',ssrc,ssrcmac,"(null)");
      string ssrcn, ssrciface;
      split_two(ssrcmac,'/',ssrcn,ssrciface,"(null)");
      fstring src = ssrc;
      fstring srcmac = ssrcmac;
      fstring srciface = ssrciface;
      string sdst,sdstmac;
      split_two(parsed_line[3],':',sdst,sdstmac,"(null)");
      string sdstn, sdstiface;
      split_two(sdstmac,'/',sdstn,sdstiface,"(null)");
      fstring dst(sdst), dstmac(sdstmac), dstiface(sdstiface);
      string bw = parsed_line[4];
      string delay = parsed_line[5];
      string loss = parsed_line[6];
      fstring link_type = parsed_line[7];
      int ibw,idelay;
      double gloss;

      if ((sscanf(bw.c_str(),"%d",&ibw) != 1) ||
	  (sscanf(delay.c_str(),"%d",&idelay) != 1) ||
	  (sscanf(loss.c_str(),"%lg",&gloss) != 1)) {
	ptop_error("Bad link line, bad delay characteristics.");
      }

      if (ibw <= 0) {
          ptop_error("Bad link line - negative or zero bandwidth.");
      }

#define ISSWITCH(n) (n->types.find("switch") != n->types.end())
      // Check to make sure the nodes in the link actually exist
      if (pname2vertex.find(src) == pname2vertex.end()) {
	  ptop_error("Bad link line, non-existent src node " << src);
	  continue;
      }
      if (pname2vertex.find(dst) == pname2vertex.end()) {
	  ptop_error("Bad link line, non-existent dst node " << dst);
	  continue;
      }

      pvertex srcv = pname2vertex[src];
      pvertex dstv = pname2vertex[dst];
      tb_pnode *srcnode = get(pvertex_pmap,srcv);
      tb_pnode *dstnode = get(pvertex_pmap,dstv);

      for (int cur = 0;cur<num;++cur) {
	pedge pe = (add_edge(srcv,dstv,pg)).first;
	tb_plink *pl = new
	    tb_plink(name,tb_plink::PLINK_NORMAL,link_type,srcnode->name,srcmac,
		     srciface,dstnode->name,dstmac,dstiface);
	put(pedge_pmap,pe,pl);
	pl->delay_info.bandwidth = ibw;
	pl->delay_info.delay = idelay;
	pl->delay_info.loss = gloss;
#if 0
#ifdef FIX_PLINK_ENDPOINTS
	pl->fixends = fixends;
#endif
#endif
#ifdef PENALIZE_BANDWIDTH
	pl->penalty = penalty;
#endif
	if (ISSWITCH(srcnode) && ISSWITCH(dstnode)) {
	  if (cur != 0) {
	    cout <<
	      "Warning: Extra links between switches will be ignored. (" <<
	      name << ")" << endl;
	  } else {
	    svertex src_switch = get(pvertex_pmap,srcv)->sgraph_switch;
	    svertex dst_switch = get(pvertex_pmap,dstv)->sgraph_switch;
	    sedge swedge = add_edge(src_switch,dst_switch,sg).first;
	    tb_slink *sl = new tb_slink();
	    put(sedge_pmap,swedge,sl);
	    sl->mate = pe;
	    pl->is_type = tb_plink::PLINK_INTERSWITCH;
	  }
	}
	srcnode->total_interfaces++;
	dstnode->total_interfaces++;
	srcnode->link_counts[link_type]++;
	dstnode->link_counts[link_type]++;
	// There can be more than one link type
	for (size_t i = 8; i < parsed_line.size(); i++) {
	  fstring extra_link_type = parsed_line[i];
	  pl->types.insert(extra_link_type);
	  srcnode->link_counts[extra_link_type]++;
	  dstnode->link_counts[extra_link_type]++;
	}
	if (ISSWITCH(srcnode) &&
	    ! ISSWITCH(dstnode)) {
	  dstnode->switches.insert(srcv);
#ifdef PER_VNODE_TT
	  dstnode->total_bandwidth += ibw;
#endif
	}
	else if (ISSWITCH(dstnode) &&
		 ! ISSWITCH(srcnode)) {
	  srcnode->switches.insert(dstv);
#ifdef PER_VNODE_TT
	  srcnode->total_bandwidth += ibw;
#endif
	} else {
          // Neither is a switch - a direct node->node link
#ifdef PER_VNODE_TT
          dstnode->total_bandwidth += ibw;
          srcnode->total_bandwidth += ibw;
#endif
        }
      }
    } else if (command == "set-type-limit") {
      if (parsed_line.size() != 3) {
	ptop_error("Bad set-type-limit line, requires two arguments.");
      }
      fstring type = parsed_line[1];
      int max;
      if (sscanf(parsed_line[2].c_str(),"%u",&max) != 1) {
	  ptop_error("Bad number argument: " << parsed_line[2] << ".");
      }

      // Look for a record for this ptype - create it if it doesn't exist
      if (ptypes.find(type) == ptypes.end()) {
	  ptypes[type] = new tb_ptype(type);
      }

      ptypes[type]->set_max_users(max);
    } else if (command == "policy") {
	if (parsed_line.size() < 3) {
	    ptop_error("No policy type given.");
	} else {
	    if (parsed_line[1] == "desire") {
		fstring desire = parsed_line[2];
		fstring type = parsed_line[3];
		tb_featuredesire *fd_obj =
		    tb_featuredesire::get_featuredesire_by_name(desire);
		if (fd_obj != NULL) {
		    if (type == "disallow") {
			fd_obj->disallow_desire();
		    } else if (type == "limit") {
			if (parsed_line.size() != 5) {
			    ptop_error("Missing desire limit");
			} else {
			    double limit;
			    if (sscanf(parsed_line[4].c_str(),"%lf",&limit)
				    != 1) {
				ptop_error("Malformed desire limit");
			    } else {
				fd_obj->limit_desire(limit);
			    }
			}
		    } else {
			ptop_error("Unknown policy for desire");
		    }
		} else {
		ptop_error("Only desire policies are supported.");
	    }
	}
	}
    } else {
      ptop_error("Unknown directive: " << command << ".");
    }
  }

  errors += bind_ptop_subnodes(pg);

  if (errors > 0) {exit(EXIT_FATAL);}

  return num_nodes;
}

<commit_msg>Double the size of assign's ptop line parse buffer<commit_after>/*
 * Copyright (c) 2000-2010 University of Utah and the Flux Group.
 *
 * {{{EMULAB-LICENSE
 *
 * This file is part of the Emulab network testbed software.
 *
 * This file is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 *
 * This file is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * }}}
 */

static const char rcsid[] = "$Id: parse_ptop.cc,v 1.44 2009-05-20 18:06:08 tarunp Exp $";

#include "port.h"

#include <boost/graph/adjacency_list.hpp>

#include <iostream>

#include <stdio.h>

using namespace boost;

#include "delay.h"
#include "physical.h"
#include "parser.h"

#include <string>
using namespace std;

extern name_pvertex_map pname2vertex;

#define ptop_error(s) errors++;cout << "PTOP:" << line << ": " << s << endl; exit(EXIT_FATAL)
#define ptop_error_noline(s) errors++;cout << "PTOP: " << s << endl

// Used to do late binding of subnode names to pnodes, so that we're no
// dependant on their ordering in the ptop file, which can be annoying to get
// right.
// Returns the number of errors found
int bind_ptop_subnodes(tb_pgraph &pg) {
    int errors = 0;

    // Iterate through all pnodes looking for ones that are subnodes
    pvertex_iterator vit,vendit;
    tie(vit,vendit) = vertices(pg);
    for (;vit != vendit;++vit) {
	tb_pnode *pnode = get(pvertex_pmap,*vit);
	if (!pnode->subnode_of_name.empty()) {
	    if (pname2vertex.find(pnode->subnode_of_name) ==
		    pname2vertex.end()) {
		ptop_error_noline(pnode->name << " is a subnode of a " <<
			"non-existent node, " << pnode->subnode_of_name << ".");
			continue;
		}
		pvertex parent_pv = pname2vertex[pnode->subnode_of_name];
		pnode->subnode_of = get(pvertex_pmap,parent_pv);
		pnode->subnode_of->has_subnode = true;
	}
    }

    return errors;
}

int parse_ptop(tb_pgraph &pg, tb_sgraph &sg, istream& input)
{
  int num_nodes = 0;
  int line=0,errors=0;
  char inbuf[32768];
  string_vector parsed_line;

  while (!input.eof()) {
    line++;
    input.getline(inbuf,32768);
    parsed_line = split_line(inbuf,' ');
    if (parsed_line.size() == 0) {continue;}

    string command = parsed_line[0];

    if (command == "node") {
      if (parsed_line.size() < 3) {
	ptop_error("Bad node line, too few arguments.");
      } else {
	num_nodes++;
	fstring name = parsed_line[1];
	bool isswitch = false;
	pvertex pv = add_vertex(pg);
	tb_pnode *p = new tb_pnode(name);
	put(pvertex_pmap,pv,p);

	unsigned int i;
	for (i = 2;
	     (i < parsed_line.size()) &&
	       (parsed_line[i] != "-");++i) {
	  string stype,load;
	  if (split_two(parsed_line[i],':',stype,load,"1") != 0) {
	    ptop_error("Bad node line, no load for type: " << stype << ".");
	  }
          fstring type(stype);
	  // Check to see if this is a static type
	  bool is_static = false;
	  if (type[0] == '*') {
	    is_static = true;
	    type.pop_front();
	  }
	  int iload;
	  if (load == "*") { // Allow * to mean unlimited
            // (okay, a really big number)
	    iload = 10000;
	  } else if (sscanf(load.c_str(),"%d",&iload) != 1) {
	    ptop_error("Bad node line, bad load: " << load << ".");
	    iload = 1;
	  }

	  /*
	   * Make a tb_ptype structure for this guy - or just add this node to
	   * it if it already exists
	   */
	  if (ptypes.find(type) == ptypes.end()) {
	      ptypes[type] = new tb_ptype(type);
	  }
	  ptypes[type]->add_slots(iload);
	  tb_ptype *ptype = ptypes[type];

	  if (type == "switch") {
	    isswitch = true;
	    p->is_switch = true;
	    p->types["switch"] = new tb_pnode::type_record(1,false,ptype);
	    svertex sv = add_vertex(sg);
	    tb_switch *s = new tb_switch();
	    put(svertex_pmap,sv,s);
	    s->mate = pv;
	    p->sgraph_switch = sv;
	    p->switches.insert(pv);
	  } else {
	    p->types[type] = new tb_pnode::type_record(iload,is_static,ptype);
	  }
	  p->type_list.push_back(p->types[type]);
	}
	for (i=i+1;(i<parsed_line.size()) && (parsed_line[i] != "-") ;++i) {
	  string sfeature,cost;
	  if (split_two(parsed_line[i],':',sfeature,cost,"0") != 0) {
	    ptop_error("Bad node line, no cost for feature: " <<
		       sfeature << ".");
	  }
      fstring feature(sfeature);

	  double gcost;
	  if (sscanf(cost.c_str(),"%lg",&gcost) != 1) {
	    ptop_error("Bad node line, bad cost: " << gcost << ".");
	    gcost = 0;
	  }

	  p->features.push_front(tb_node_featuredesire(feature,gcost));

	}
	/*
	 * Parse any other node options or flags
	 */
	for (i=i+1; i < parsed_line.size(); ++i) {
	    string flag,value;
	    split_two(parsed_line[i],':',flag,value,"(null)");
	    if (flag == "trivial_bw") {
		// Handle trivial bandwidth spec
		int trivial_bw;
		if (sscanf(value.c_str(),"%i",&trivial_bw) != 1) {
		    ptop_error("Bad bandwidth given for trivial_bw: " << value
			    << endl);
		    trivial_bw = 0;
		}
		p->trivial_bw = trivial_bw;
	    } else if (flag == "subnode_of") {
		// Handle subnode relationships
		if (!p->subnode_of_name.empty()) {
		    ptop_error("Can't be a subnode of two nodes");
		    continue;
		} else {
		    // Just store the name for now, we'll do late binding to
		    // an actual pnode later
		    p->subnode_of_name = value;
		}
	    } else if (flag == "unique") {
		// Means that we should never put this pnode into a ptype with
		// other pnodes
		p->unique = true;
	    } else {
		ptop_error("Bad flag given: " << flag << ".");
	    }
	}
	p->features.sort();
	pname2vertex[name] = pv;
      }
    } else if (command == "link") {
      if (parsed_line.size() < 8) {
	ptop_error("Bad link line, too few arguments.");
      }
      int num = 1;
#ifdef PENALIZE_BANDWIDTH
      float penalty;
      if (parsed_line.size() == 9) {
	if (sscanf(parsed_line[8].c_str(),"%f",&penalty) != 1) {
	  ptop_error("Bad number argument: " << parsed_line[8] << ".");
	  penalty=1.0;
	}
      }
#endif

#if 0
#ifdef FIX_PLINK_ENDPOINTS
      bool fixends;
#ifdef FIX_PLINKS_DEFAULT
      fixends = true;
#else
      fixends = false;
#endif
      if (parsed_line.size() == 10) {
	  if (parsed_line[9] == "fixends") {
	      fixends = true;
	  }
      }
#else
      if (parsed_line.size() > 9) {
	ptop_error("Bad link line, too many arguments.");
      }
#endif
#endif

      fstring name = parsed_line[1];
      string ssrc,ssrcmac;
      split_two(parsed_line[2],':',ssrc,ssrcmac,"(null)");
      string ssrcn, ssrciface;
      split_two(ssrcmac,'/',ssrcn,ssrciface,"(null)");
      fstring src = ssrc;
      fstring srcmac = ssrcmac;
      fstring srciface = ssrciface;
      string sdst,sdstmac;
      split_two(parsed_line[3],':',sdst,sdstmac,"(null)");
      string sdstn, sdstiface;
      split_two(sdstmac,'/',sdstn,sdstiface,"(null)");
      fstring dst(sdst), dstmac(sdstmac), dstiface(sdstiface);
      string bw = parsed_line[4];
      string delay = parsed_line[5];
      string loss = parsed_line[6];
      fstring link_type = parsed_line[7];
      int ibw,idelay;
      double gloss;

      if ((sscanf(bw.c_str(),"%d",&ibw) != 1) ||
	  (sscanf(delay.c_str(),"%d",&idelay) != 1) ||
	  (sscanf(loss.c_str(),"%lg",&gloss) != 1)) {
	ptop_error("Bad link line, bad delay characteristics.");
      }

      if (ibw <= 0) {
          ptop_error("Bad link line - negative or zero bandwidth.");
      }

#define ISSWITCH(n) (n->types.find("switch") != n->types.end())
      // Check to make sure the nodes in the link actually exist
      if (pname2vertex.find(src) == pname2vertex.end()) {
	  ptop_error("Bad link line, non-existent src node " << src);
	  continue;
      }
      if (pname2vertex.find(dst) == pname2vertex.end()) {
	  ptop_error("Bad link line, non-existent dst node " << dst);
	  continue;
      }

      pvertex srcv = pname2vertex[src];
      pvertex dstv = pname2vertex[dst];
      tb_pnode *srcnode = get(pvertex_pmap,srcv);
      tb_pnode *dstnode = get(pvertex_pmap,dstv);

      for (int cur = 0;cur<num;++cur) {
	pedge pe = (add_edge(srcv,dstv,pg)).first;
	tb_plink *pl = new
	    tb_plink(name,tb_plink::PLINK_NORMAL,link_type,srcnode->name,srcmac,
		     srciface,dstnode->name,dstmac,dstiface);
	put(pedge_pmap,pe,pl);
	pl->delay_info.bandwidth = ibw;
	pl->delay_info.delay = idelay;
	pl->delay_info.loss = gloss;
#if 0
#ifdef FIX_PLINK_ENDPOINTS
	pl->fixends = fixends;
#endif
#endif
#ifdef PENALIZE_BANDWIDTH
	pl->penalty = penalty;
#endif
	if (ISSWITCH(srcnode) && ISSWITCH(dstnode)) {
	  if (cur != 0) {
	    cout <<
	      "Warning: Extra links between switches will be ignored. (" <<
	      name << ")" << endl;
	  } else {
	    svertex src_switch = get(pvertex_pmap,srcv)->sgraph_switch;
	    svertex dst_switch = get(pvertex_pmap,dstv)->sgraph_switch;
	    sedge swedge = add_edge(src_switch,dst_switch,sg).first;
	    tb_slink *sl = new tb_slink();
	    put(sedge_pmap,swedge,sl);
	    sl->mate = pe;
	    pl->is_type = tb_plink::PLINK_INTERSWITCH;
	  }
	}
	srcnode->total_interfaces++;
	dstnode->total_interfaces++;
	srcnode->link_counts[link_type]++;
	dstnode->link_counts[link_type]++;
	// There can be more than one link type
	for (size_t i = 8; i < parsed_line.size(); i++) {
	  fstring extra_link_type = parsed_line[i];
	  pl->types.insert(extra_link_type);
	  srcnode->link_counts[extra_link_type]++;
	  dstnode->link_counts[extra_link_type]++;
	}
	if (ISSWITCH(srcnode) &&
	    ! ISSWITCH(dstnode)) {
	  dstnode->switches.insert(srcv);
#ifdef PER_VNODE_TT
	  dstnode->total_bandwidth += ibw;
#endif
	}
	else if (ISSWITCH(dstnode) &&
		 ! ISSWITCH(srcnode)) {
	  srcnode->switches.insert(dstv);
#ifdef PER_VNODE_TT
	  srcnode->total_bandwidth += ibw;
#endif
	} else {
          // Neither is a switch - a direct node->node link
#ifdef PER_VNODE_TT
          dstnode->total_bandwidth += ibw;
          srcnode->total_bandwidth += ibw;
#endif
        }
      }
    } else if (command == "set-type-limit") {
      if (parsed_line.size() != 3) {
	ptop_error("Bad set-type-limit line, requires two arguments.");
      }
      fstring type = parsed_line[1];
      int max;
      if (sscanf(parsed_line[2].c_str(),"%u",&max) != 1) {
	  ptop_error("Bad number argument: " << parsed_line[2] << ".");
      }

      // Look for a record for this ptype - create it if it doesn't exist
      if (ptypes.find(type) == ptypes.end()) {
	  ptypes[type] = new tb_ptype(type);
      }

      ptypes[type]->set_max_users(max);
    } else if (command == "policy") {
	if (parsed_line.size() < 3) {
	    ptop_error("No policy type given.");
	} else {
	    if (parsed_line[1] == "desire") {
		fstring desire = parsed_line[2];
		fstring type = parsed_line[3];
		tb_featuredesire *fd_obj =
		    tb_featuredesire::get_featuredesire_by_name(desire);
		if (fd_obj != NULL) {
		    if (type == "disallow") {
			fd_obj->disallow_desire();
		    } else if (type == "limit") {
			if (parsed_line.size() != 5) {
			    ptop_error("Missing desire limit");
			} else {
			    double limit;
			    if (sscanf(parsed_line[4].c_str(),"%lf",&limit)
				    != 1) {
				ptop_error("Malformed desire limit");
			    } else {
				fd_obj->limit_desire(limit);
			    }
			}
		    } else {
			ptop_error("Unknown policy for desire");
		    }
		} else {
		ptop_error("Only desire policies are supported.");
	    }
	}
	}
    } else {
      ptop_error("Unknown directive: " << command << ".");
    }
  }

  errors += bind_ptop_subnodes(pg);

  if (errors > 0) {exit(EXIT_FATAL);}

  return num_nodes;
}

<|endoftext|>


<commit_before>#include "../include/secnet.h"

void SecNet::Initialize(std::string listen, std::string certificateFile, std::string privateKeyFile, std::string dhParamFile, std::string tlsCipherList)
{
	SSL_library_init();
	SSL_load_error_strings();
	SSL_METHOD* serverMethod = (SSL_METHOD*)TLSv1_2_server_method();
	SSL_CTX* serverContext = SSL_CTX_new(serverMethod);

	if(!sslServerContext)
	{
		std::cout << "SSL_CTX_new() failed!" << std::endl;
		exit(-1);
	}

	int status = SSL_CTX_use_certificate_file(serverContext, certificateFile.c_str(), SSL_FILETYPE_PEM);

	if(status <= 0)
	{
		std::cout << "Could not load certificate-file!" << std::endl;
		exit(-1);
	}

	status = SSL_CTX_use_PrivateKey_file(serverContext, privateKeyFile.c_str(), SSL_FILETYPE_PEM);

	if(status <= 0)
	{
		std::cout << "Could not load private-key-file!" << std::endl:
		exit(-1);
	}

	if(!SSL_CTX_check_private_key(serverContext))
	{
		std::cout << "SSL-certificate and private-key don't belong together!" << std::endl;
		exit(-1);
	}

	long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
	status = SSL_CTX_set_options(serverContext, sslopt);

	if(status <= 0)
	{
		std::cout << "Could not set SSL options!" << std::endl;
		exit(-1);
	}

	DH* dh = PEM_read_DHparams(dhParamFile.c_str(), NULL, NULL, NULL);
	status = SSL_CTX_set_tmp_dh(serverContext, dh);

	if(status <= 0)
	{
		std::cout << "Could not load dhparam-file!" << std::endl;
		exit(-1);
	}

	if(tlsCipherList != "")
	{
		status = SSL_CTX_set_cipher_list(serverContext, tlsCipherList.c_str());

		if(status <= 0)
		{
			std::cout << "Could not set TLS cipher list!" << std::endl;
			exit(-1);
		}
	}

	_serverSocket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

	if(_serverSocket == -1)
	{
		std::cout << "socket() failed!" << std::endl;
		exit(-1);
	}

	struct sockaddr_in6 address;
	bzero(&address, sizeof(address));
	address.sin6_family = AF_INET6;
	address.sin6_port = htons(DefaultPort);
	address.sin6_addr = in6addr_any;

	status = bind(_serverSocket, (struct sockaddr*)&address, sizeof(address));

	if(status != 0)
	{
		std::cout << "bind() failed!" << std::endl;
		exit(-1);
	}

	status = listen(_serverSocket, SOMAXCONN);

	if(status != 0)
	{
		std::cout << "listen() failed!" << std::endl;
		exit(-1);
	}

	ListenLoop(serverContext);
}
<commit_msg>Fixed compiler errors<commit_after>#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>

#include "../include/secnet.h"

void SecNet::Initialize(std::string listenAddress, std::string certificateFile, std::string privateKeyFile, std::string dhParamFile, std::string tlsCipherList)
{
	SSL_library_init();
	SSL_load_error_strings();
	SSL_METHOD* serverMethod = (SSL_METHOD*)TLSv1_2_server_method();
	SSL_CTX* serverContext = SSL_CTX_new(serverMethod);

	if(!serverContext)
	{
		std::cout << "SSL_CTX_new() failed!" << std::endl;
		exit(-1);
	}

	int status = SSL_CTX_use_certificate_file(serverContext, certificateFile.c_str(), SSL_FILETYPE_PEM);

	if(status <= 0)
	{
		std::cout << "Could not load certificate-file!" << std::endl;
		exit(-1);
	}

	status = SSL_CTX_use_PrivateKey_file(serverContext, privateKeyFile.c_str(), SSL_FILETYPE_PEM);

	if(status <= 0)
	{
		std::cout << "Could not load private-key-file!" << std::endl;
		exit(-1);
	}

	if(!SSL_CTX_check_private_key(serverContext))
	{
		std::cout << "SSL-certificate and private-key don't belong together!" << std::endl;
		exit(-1);
	}

	long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
	status = SSL_CTX_set_options(serverContext, sslopt);

	if(status <= 0)
	{
		std::cout << "Could not set SSL options!" << std::endl;
		exit(-1);
	}

	FILE* dhFile = fopen(dhParamFile.c_str(), "rb");
	DH* dh = PEM_read_DHparams(dhFile, NULL, NULL, NULL);
	fclose(dhFile);
	status = SSL_CTX_set_tmp_dh(serverContext, dh);

	if(status <= 0)
	{
		std::cout << "Could not load dhparam-file!" << std::endl;
		exit(-1);
	}

	if(tlsCipherList != "")
	{
		status = SSL_CTX_set_cipher_list(serverContext, tlsCipherList.c_str());

		if(status <= 0)
		{
			std::cout << "Could not set TLS cipher list!" << std::endl;
			exit(-1);
		}
	}

	_serverSocket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

	if(_serverSocket == -1)
	{
		std::cout << "socket() failed!" << std::endl;
		exit(-1);
	}

	struct sockaddr_in6 address;
	bzero(&address, sizeof(address));
	address.sin6_family = AF_INET6;
	address.sin6_port = htons(SecNet::DefaultPort);
	address.sin6_addr = in6addr_any;

	status = bind(_serverSocket, (struct sockaddr*)&address, sizeof(address));

	if(status != 0)
	{
		std::cout << "bind() failed!" << std::endl;
		exit(-1);
	}

	status = listen(_serverSocket, SOMAXCONN);

	if(status != 0)
	{
		std::cout << "listen() failed!" << std::endl;
		exit(-1);
	}

	ListenLoop(serverContext);
}

<|endoftext|>


<commit_before>// @(#)root/hist:$Id$
// Author: David Gonzalez Maline   12/11/09

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TFitResult.h"
#include "Math/WrappedMultiTF1.h"

#include <iostream>

/** \class TFitResult
    \ingroup Hist
Extends the ROOT::Fit::Result class with a TNamed inheritance
providing easy possibility for I/O
*/

ClassImp(TFitResult);

////////////////////////////////////////////////////////////////////////////////
/// Constructor from a ROOT::Fit::FitResult
/// copy the contained TF1 pointer function if it is

TFitResult::TFitResult(const ROOT::Fit::FitResult& f) :
   TNamed("TFitResult","TFitResult"),
   ROOT::Fit::FitResult(f)
{
   ROOT::Math::WrappedMultiTF1 * wfunc = dynamic_cast<ROOT::Math::WrappedMultiTF1 *>(ModelFunction().get() );
   if (wfunc)  wfunc->SetAndCopyFunction();
}

////////////////////////////////////////////////////////////////////////////////
/// Print result of the fit, by default chi2, parameter values and errors.
/// if option "V" is given print also error matrix and correlation

void TFitResult::Print(Option_t *option) const
{
   TString opt(option);
   opt.ToUpper();
   bool doCovMat = opt.Contains("V");
   ROOT::Fit::FitResult::Print( std::cout, doCovMat);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the covariance matrix from fit
///
/// The matrix is a symmetric matrix with a size N equal to
/// the total number of parameters considered in the fit including the fixed ones
/// The matrix row and columns corresponding to the fixed parameters will contain only zero's

TMatrixDSym TFitResult::GetCovarianceMatrix()  const
{
   if (CovMatrixStatus() == 0) {
      Warning("GetCovarianceMatrix","covariance matrix is not available");
      return TMatrixDSym();
   }
   TMatrixDSym mat(NPar());
   ROOT::Fit::FitResult::GetCovarianceMatrix<TMatrixDSym>(mat);
   return mat;
}

////////////////////////////////////////////////////////////////////////////////
/// Return the correlation matrix from fit.
///
/// The matrix is a symmetric matrix with a size N equal to
/// the total number of parameters considered in the fit including the fixed ones
/// The matrix row and columns corresponding to the fixed parameters will contain only zero's

TMatrixDSym TFitResult::GetCorrelationMatrix()  const
{
   if (CovMatrixStatus() == 0) {
      Warning("GetCorrelationMatrix","correlation matrix is not available");
      return TMatrixDSym();
   }
   TMatrixDSym mat(NPar());
   ROOT::Fit::FitResult::GetCorrelationMatrix<TMatrixDSym>(mat);
   return mat;
}

////////////////////////////////////////////////////////////////////////////////
/// Print the TFitResult.

std::string cling::printValue(const TFitResult* val) {
   std::string buf;
   std::stringstream outs(buf);
   val->ROOT::Fit::FitResult::Print(outs, false /*doCovMat*/);
   return buf;
}
<commit_msg>This is not an llvm stream!<commit_after>// @(#)root/hist:$Id$
// Author: David Gonzalez Maline   12/11/09

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TFitResult.h"
#include "Math/WrappedMultiTF1.h"

#include <iostream>

/** \class TFitResult
    \ingroup Hist
Extends the ROOT::Fit::Result class with a TNamed inheritance
providing easy possibility for I/O
*/

ClassImp(TFitResult);

////////////////////////////////////////////////////////////////////////////////
/// Constructor from a ROOT::Fit::FitResult
/// copy the contained TF1 pointer function if it is

TFitResult::TFitResult(const ROOT::Fit::FitResult& f) :
   TNamed("TFitResult","TFitResult"),
   ROOT::Fit::FitResult(f)
{
   ROOT::Math::WrappedMultiTF1 * wfunc = dynamic_cast<ROOT::Math::WrappedMultiTF1 *>(ModelFunction().get() );
   if (wfunc)  wfunc->SetAndCopyFunction();
}

////////////////////////////////////////////////////////////////////////////////
/// Print result of the fit, by default chi2, parameter values and errors.
/// if option "V" is given print also error matrix and correlation

void TFitResult::Print(Option_t *option) const
{
   TString opt(option);
   opt.ToUpper();
   bool doCovMat = opt.Contains("V");
   ROOT::Fit::FitResult::Print( std::cout, doCovMat);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the covariance matrix from fit
///
/// The matrix is a symmetric matrix with a size N equal to
/// the total number of parameters considered in the fit including the fixed ones
/// The matrix row and columns corresponding to the fixed parameters will contain only zero's

TMatrixDSym TFitResult::GetCovarianceMatrix()  const
{
   if (CovMatrixStatus() == 0) {
      Warning("GetCovarianceMatrix","covariance matrix is not available");
      return TMatrixDSym();
   }
   TMatrixDSym mat(NPar());
   ROOT::Fit::FitResult::GetCovarianceMatrix<TMatrixDSym>(mat);
   return mat;
}

////////////////////////////////////////////////////////////////////////////////
/// Return the correlation matrix from fit.
///
/// The matrix is a symmetric matrix with a size N equal to
/// the total number of parameters considered in the fit including the fixed ones
/// The matrix row and columns corresponding to the fixed parameters will contain only zero's

TMatrixDSym TFitResult::GetCorrelationMatrix()  const
{
   if (CovMatrixStatus() == 0) {
      Warning("GetCorrelationMatrix","correlation matrix is not available");
      return TMatrixDSym();
   }
   TMatrixDSym mat(NPar());
   ROOT::Fit::FitResult::GetCorrelationMatrix<TMatrixDSym>(mat);
   return mat;
}

////////////////////////////////////////////////////////////////////////////////
/// Print the TFitResult.

std::string cling::printValue(const TFitResult* val) {
   std::stringstream outs;
   val->ROOT::Fit::FitResult::Print(outs, false /*doCovMat*/);
   return outs.str();
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkSQLDatabase.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkToolkits.h"
#include "vtkSQLDatabase.h"
#include "vtkSQLiteDatabase.h"

#ifdef VTK_USE_POSTGRES
#include "vtkPostgreSQLDatabase.h"
#endif // VTK_USE_POSTGRES

#ifdef VTK_USE_MYSQL
#include "vtkMySQLDatabase.h"
#endif // VTK_USE_MYSQL

#include "vtkObjectFactory.h"

#include <vtksys/SystemTools.hxx>

vtkCxxRevisionMacro(vtkSQLDatabase, "1.9");

// ----------------------------------------------------------------------
vtkSQLDatabase::vtkSQLDatabase()
{
}

// ----------------------------------------------------------------------
vtkSQLDatabase::~vtkSQLDatabase()
{
}

// ----------------------------------------------------------------------
void vtkSQLDatabase::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

// ----------------------------------------------------------------------
vtkSQLDatabase* vtkSQLDatabase::CreateFromURL( const char* URL )
{
  vtkstd::string protocol;
  vtkstd::string username;
  vtkstd::string password;
  vtkstd::string hostname;
  vtkstd::string dataport;
  vtkstd::string database;
  vtkstd::string dataglom;
  vtkSQLDatabase* db = 0;

  // Sqlite is a bit special so lets get that out of the way :)
  if ( ! vtksys::SystemTools::ParseURLProtocol( URL, protocol, dataglom))
    {
    vtkGenericWarningMacro( "Invalid URL: " << URL );
    return 0;
    }
  if ( protocol == "sqlite" )
    {
    db = vtkSQLiteDatabase::New();
    vtkSQLiteDatabase *sqlite_db = vtkSQLiteDatabase::SafeDownCast(db);
    sqlite_db->SetDatabaseFileName(dataglom.c_str());
    return db;
    }

  // Okay now for all the other database types get more detailed info
  if ( ! vtksys::SystemTools::ParseURL( URL, protocol, username,
                                password, hostname, dataport, database) )
    {
    vtkGenericWarningMacro( "Invalid URL: " << URL );
    return 0;
    }

#ifdef VTK_USE_POSTGRES
  if ( protocol == "psql" )
    {
    db = vtkPostgreSQLDatabase::New();
    vtkPostgreSQLDatabase *post_db = vtkPostgreSQLDatabase::SafeDownCast(db);
    post_db->SetUserName(username.c_str());
    post_db->SetPassword(password.c_str());
    post_db->SetHostName(hostname.c_str());
    post_db->SetPort(atoi(dataport.c_str()));
    post_db->SetDatabaseName(database.c_str());
    }
#endif // VTK_USE_POSTGRES
#ifdef VTK_USE_MYSQL
  else if ( protocol == "mysql" )
    {
    db = vtkMySQLDatabase::New();
    vtkMySQLDatabase *mysql_db = vtkMySQLDatabase::SafeDownCast(db);
    mysql_db->SetUserName(username.c_str());
    mysql_db->SetPassword(password.c_str());
    mysql_db->SetHostName(hostname.c_str());
    mysql_db->SetPort(atoi(dataport.c_str()));
    mysql_db->SetDatabaseName(database.c_str());
    }
#endif // VTK_USE_MYSQL
  else
    {
    vtkGenericWarningMacro( "Unsupported protocol: " << protocol.c_str() );
    return 0;
    }

  return db;
}

<commit_msg>COMP: Method names changed to avoid Windows name mangling.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkSQLDatabase.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkToolkits.h"
#include "vtkSQLDatabase.h"
#include "vtkSQLiteDatabase.h"

#ifdef VTK_USE_POSTGRES
#include "vtkPostgreSQLDatabase.h"
#endif // VTK_USE_POSTGRES

#ifdef VTK_USE_MYSQL
#include "vtkMySQLDatabase.h"
#endif // VTK_USE_MYSQL

#include "vtkObjectFactory.h"

#include <vtksys/SystemTools.hxx>

vtkCxxRevisionMacro(vtkSQLDatabase, "1.10");

// ----------------------------------------------------------------------
vtkSQLDatabase::vtkSQLDatabase()
{
}

// ----------------------------------------------------------------------
vtkSQLDatabase::~vtkSQLDatabase()
{
}

// ----------------------------------------------------------------------
void vtkSQLDatabase::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

// ----------------------------------------------------------------------
vtkSQLDatabase* vtkSQLDatabase::CreateFromURL( const char* URL )
{
  vtkstd::string protocol;
  vtkstd::string username;
  vtkstd::string password;
  vtkstd::string hostname;
  vtkstd::string dataport;
  vtkstd::string database;
  vtkstd::string dataglom;
  vtkSQLDatabase* db = 0;

  // Sqlite is a bit special so lets get that out of the way :)
  if ( ! vtksys::SystemTools::ParseURLProtocol( URL, protocol, dataglom))
    {
    vtkGenericWarningMacro( "Invalid URL: " << URL );
    return 0;
    }
  if ( protocol == "sqlite" )
    {
    db = vtkSQLiteDatabase::New();
    vtkSQLiteDatabase *sqlite_db = vtkSQLiteDatabase::SafeDownCast(db);
    sqlite_db->SetDatabaseFileName(dataglom.c_str());
    return db;
    }

  // Okay now for all the other database types get more detailed info
  if ( ! vtksys::SystemTools::ParseURL( URL, protocol, username,
                                password, hostname, dataport, database) )
    {
    vtkGenericWarningMacro( "Invalid URL: " << URL );
    return 0;
    }

#ifdef VTK_USE_POSTGRES
  if ( protocol == "psql" )
    {
    db = vtkPostgreSQLDatabase::New();
    vtkPostgreSQLDatabase *post_db = vtkPostgreSQLDatabase::SafeDownCast(db);
    post_db->SetUserName(username.c_str());
    post_db->SetPassword(password.c_str());
    post_db->SetHostName(hostname.c_str());
    post_db->SetServerPort(atoi(dataport.c_str()));
    post_db->SetDatabaseName(database.c_str());
    }
#endif // VTK_USE_POSTGRES
#ifdef VTK_USE_MYSQL
  else if ( protocol == "mysql" )
    {
    db = vtkMySQLDatabase::New();
    vtkMySQLDatabase *mysql_db = vtkMySQLDatabase::SafeDownCast(db);
    mysql_db->SetUserName(username.c_str());
    mysql_db->SetPassword(password.c_str());
    mysql_db->SetHostName(hostname.c_str());
    mysql_db->SetServerPort(atoi(dataport.c_str()));
    mysql_db->SetDatabaseName(database.c_str());
    }
#endif // VTK_USE_MYSQL
  else
    {
    vtkGenericWarningMacro( "Unsupported protocol: " << protocol.c_str() );
    return 0;
    }

  return db;
}

<|endoftext|>


<commit_before><commit_msg>stt: use double in write_svg for small tree accuracy<commit_after><|endoftext|>


<commit_before>#include "backpropagation.hpp"

using namespace Convolutional::Learning;

auto Backpropagation::IsFinished() -> bool {
static int runs = 2;
return !runs--;
}<commit_msg>Remove implementation file of class template<commit_after><|endoftext|>


<commit_before>/**
 * @file discrete.cc
 *
 * Helpers for discrete math (implementation).
 */

#include "discrete.h"
#include "fastlib/fx/io.h"

#include <stdlib.h>

double math::BinomialCoefficient(int n, int k) {
  int n_k = n - k;
  double nchsk = 1;
  int i;

  if(k > n || k < 0) {
    return 0;
  }

  if(k < n_k) {
    k = n_k;
    n_k = n - k;
  }

  for(i = 1; i <= n_k; i++) {
    nchsk *= (++k);
    nchsk /= i;
  }
  return nchsk;
}

double math::Factorial(int d) {
  double v = 1;

  mlpack::IO::Assert(d >= 0);

  for (int i = 2; i <= d; i++) {
    v *= i;
  }

  return v;
}

void math::MakeIdentityPermutation(size_t size, size_t *array) {
  for (size_t i = 0; i < size; i++) {
    array[i] = i;
  }
}

void math::MakeIdentityPermutation(size_t size, std::vector<size_t>& result) {
  result.reserve(size);

  for (size_t i = 0; i < size; i++)
    result.push_back(i);
}
void math::MakeRandomPermutation(size_t size, size_t *array) {
  // Regular permutation algorithm.
  // This is cache inefficient for large sizes; large caches might
  // warrant a more sophisticated blocked algorithm.

  if (size == 0) {
    return;
  }

  array[0] = 0;

  for (size_t i = 1; i < size; i++) {
    size_t victim = rand() % i;
    array[i] = array[victim];
    array[victim] = i;
  }
}

void math::MakeInversePermutation(size_t size,
    const size_t *original, size_t *reverse) {
  for (size_t i = 0; i < size; i++) {
    reverse[original[i]] = i;
  }
}
<commit_msg>Refactoring math dir : deleting unused functions from discrete.cc<commit_after>/**
 * @file discrete.cc
 *
 * Helpers for discrete math (implementation).
 */

#include "discrete.h"
#include "fastlib/fx/io.h"

#include <stdlib.h>

double math::BinomialCoefficient(int n, int k) {
  int n_k = n - k;
  double nchsk = 1;
  int i;

  if(k > n || k < 0) {
    return 0;
  }

  if(k < n_k) {
    k = n_k;
    n_k = n - k;
  }

  for(i = 1; i <= n_k; i++) {
    nchsk *= (++k);
    nchsk /= i;
  }
  return nchsk;
}
<|endoftext|>


<commit_before>/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001 Jason Winnebeck (gillius@mail.rit.edu)
 * Project website: http://www.rit.edu/~jpw9607/
 *
 * 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.1 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "../include/gnelib/gneintern.h"
#include "../include/gnelib/ConnectionEventGenerator.h"
#include "../include/gnelib/ReceiveEventListener.h"
#include "../include/gnelib/ConditionVariable.h"
#include "../include/gnelib/Connection.h"

namespace GNE {

//##ModelId=3B07538100B9
ConnectionEventGenerator::ConnectionEventGenerator()
: Thread("EventGen"), group(NL_INVALID) {
  group = nlGroupCreate();
  assert(group != NL_INVALID);
  sockBuf = new NLsocket[NL_MAX_GROUP_SOCKETS];
  gnedbgo(5, "created");
}

//##ModelId=3B07538100BA
ConnectionEventGenerator::~ConnectionEventGenerator() {
  nlGroupDestroy(group);
  delete[] sockBuf;
  gnedbgo(5, "destroyed");
}

/**
 * \bug I think it might be possible for a syncronization error to occur
 *      where an event can be generated on a Connection that is shutting
 *      down.
 * \bug If nlPollGroup fails, the error is not reported.  Instead the results
 *      are ignored, and the call is made again (or in debug mode, the
 *      assert fails).
 */
//##ModelId=3B07538100BC
void ConnectionEventGenerator::run() {
  while (!shutdown) {
    mapCtrl.acquire();
    while (connections.empty() && !shutdown) {
      mapCtrl.wait();
    }
    mapCtrl.release();
    if (!shutdown) {
      int numsockets = nlPollGroup(group, NL_READ_STATUS, sockBuf, NL_MAX_GROUP_SOCKETS, 250);
      if (numsockets != NL_INVALID) {
        numsockets--;
        for (; numsockets >= 0; numsockets--) {
          mapCtrl.acquire();
          std::map<NLsocket, ReceiveEventListener*>::iterator iter = connections.find(sockBuf[numsockets]);
          //Check to make sure the listener didn't unregister while we were waiting.
          if (iter != connections.end()) {
            //I'm 99.5% sure this won't cause deadlocks anymore, and onReceive
            //MUST be in this lock to make sure we don't call it after it has
            //been unregistered.
            iter->second->onReceive();
          }
          mapCtrl.release();
        }
      } else {
        if (!(nlGetError() == NL_SOCKET_ERROR && nlGetSystemError() == 10004)) {
          gnedbgo1(1, "%s", Error::createLowLevelError().toString().c_str());
          assert(false);
        } else
          gnedbgo(1, "nlPollGroup call canceled (perhaps to do low-level socket close).  Trying again.");
          //Else the call was canceled.  This is a bug in HawkNL I think, since cancellation
          //is different from an error.
      }
    }
  }
}

//##ModelId=3B07538100BD
void ConnectionEventGenerator::reg(NLsocket socket, ReceiveEventListener* conn) {
  assert(socket != NL_INVALID);
  mapCtrl.acquire();
  nlGroupAddSocket(group, socket);
  connections[socket] = conn;
  mapCtrl.release();
  mapCtrl.signal(); //This will wake up the daemon thread if this is the first
                    // registered, and it is sleeping.
}

//##ModelId=3B07538100DD
void ConnectionEventGenerator::unreg(NLsocket socket) {
  assert(socket != NL_INVALID);
  mapCtrl.acquire();
  assert(connections.find(socket) != connections.end());
  nlGroupDeleteSocket(group, socket);
  connections.erase(socket);
  mapCtrl.release();
}

//##ModelId=3B07538100DF
void ConnectionEventGenerator::shutDown() {
  Thread::shutDown();
  mapCtrl.signal();
}

}

<commit_msg>Updated for HawkNL 1.5b1<commit_after>/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001 Jason Winnebeck (gillius@mail.rit.edu)
 * Project website: http://www.rit.edu/~jpw9607/
 *
 * 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.1 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "../include/gnelib/gneintern.h"
#include "../include/gnelib/ConnectionEventGenerator.h"
#include "../include/gnelib/ReceiveEventListener.h"
#include "../include/gnelib/ConditionVariable.h"
#include "../include/gnelib/Connection.h"

namespace GNE {

//##ModelId=3B07538100B9
ConnectionEventGenerator::ConnectionEventGenerator()
: Thread("EventGen"), group(NL_INVALID) {
  group = nlGroupCreate();
  assert(group != NL_INVALID);
  sockBuf = new NLsocket[NL_MAX_GROUP_SOCKETS];
  gnedbgo(5, "created");
}

//##ModelId=3B07538100BA
ConnectionEventGenerator::~ConnectionEventGenerator() {
  nlGroupDestroy(group);
  delete[] sockBuf;
  gnedbgo(5, "destroyed");
}

/**
 * \bug I think it might be possible for a syncronization error to occur
 *      where an event can be generated on a Connection that is shutting
 *      down.
 * \bug If nlPollGroup fails, the error is not reported.  Instead the results
 *      are ignored, and the call is made again (or in debug mode, the
 *      assert fails).
 */
//##ModelId=3B07538100BC
void ConnectionEventGenerator::run() {
  while (!shutdown) {
    mapCtrl.acquire();
    while (connections.empty() && !shutdown) {
      mapCtrl.wait();
    }
    mapCtrl.release();
    if (!shutdown) {
      int numsockets = nlPollGroup(group, NL_READ_STATUS, sockBuf, NL_MAX_GROUP_SOCKETS, 250);
      if (numsockets != NL_INVALID) {
        numsockets--;
        for (; numsockets >= 0; numsockets--) {
          mapCtrl.acquire();
          std::map<NLsocket, ReceiveEventListener*>::iterator iter = connections.find(sockBuf[numsockets]);
          //Check to make sure the listener didn't unregister while we were waiting.
          if (iter != connections.end()) {
            //I'm 99.5% sure this won't cause deadlocks anymore, and onReceive
            //MUST be in this lock to make sure we don't call it after it has
            //been unregistered.
            iter->second->onReceive();
          }
          mapCtrl.release();
        }
      } else {
        //The only valid error is NL_INVALID_SOCKET which happens if we close
        //a socket while nlPollGroup is using it.
        if (nlGetError() != NL_INVALID_SOCKET) {
          gnedbgo1(1, "%s", Error::createLowLevelError().toString().c_str());
          assert(false);
        }
      }
    }
  }
}

//##ModelId=3B07538100BD
void ConnectionEventGenerator::reg(NLsocket socket, ReceiveEventListener* conn) {
  assert(socket != NL_INVALID);
  mapCtrl.acquire();
  nlGroupAddSocket(group, socket);
  connections[socket] = conn;
  mapCtrl.release();
  mapCtrl.signal(); //This will wake up the daemon thread if this is the first
                    // registered, and it is sleeping.
}

//##ModelId=3B07538100DD
void ConnectionEventGenerator::unreg(NLsocket socket) {
  assert(socket != NL_INVALID);
  mapCtrl.acquire();
  assert(connections.find(socket) != connections.end());
  nlGroupDeleteSocket(group, socket);
  connections.erase(socket);
  mapCtrl.release();
}

//##ModelId=3B07538100DF
void ConnectionEventGenerator::shutDown() {
  Thread::shutDown();
  mapCtrl.signal();
}

}

<|endoftext|>


<commit_before>#include "connection3.hh"
#include "result3.hh"
#include "config.h"

#if defined(HAVE_MYSQL_SHUTDOWN_LEVEL_ARG)
#	define SHUTDOWN_ARG ,SHUTDOWN_DEFAULT
#else
#	define SHUTDOWN_ARG
#endif

Connection::Connection (const char *db, const char *host, const char *user,
			const char *passwd, bool te)
  : throw_exceptions(te), locked(false)
{
	mysql_init(&mysql);
  if (real_connect (db, host, user, passwd,3306,0,60,NULL,0))
	{
    locked = false;
    Success = is_connected = true;
  }
  else
  {
    locked = false; Success = is_connected = false;
    if (throw_exceptions) throw BadQuery(error());
  }
}

Connection::Connection (const char *db, const char *host, const char *user,
			const char *passwd, uint port, my_bool compress,
			unsigned int connect_timeout, bool te,
			const char *socket_name, unsigned client_flag)
  : throw_exceptions(te), locked(false)
{
	mysql_init(&mysql);
  if (real_connect (db, host, user, passwd, port, compress,		connect_timeout,socket_name, client_flag))
  {
    locked = false;
    Success = is_connected = true;
  }
  else
  {
    locked = false; Success = is_connected = false;
    if (throw_exceptions) throw BadQuery(error());
  }
}

bool Connection::real_connect (cchar *db, cchar *host, cchar *user,
			       cchar *passwd, uint port, my_bool compress,
			       unsigned int connect_timeout,
			       const char *socket_name, unsigned int client_flag)
{
  mysql.options.compress = compress;
  mysql.options.connect_timeout=connect_timeout;
  locked = true; //mysql.options.my_cnf_file="my";

	mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, "my");

	if (mysql_real_connect(&mysql,host,user,passwd,db, port,socket_name,client_flag))
  {
    locked = false;
    Success = is_connected = true;
  }
  else
  {
    locked = false; Success = is_connected = false;
    if (throw_exceptions) throw BadQuery(error());
  }
	//	mysql.options.my_cnf_file=0;
  if (!Success) return Success;
  if (db && db[0]) // if db is not empty
    Success = select_db(db);
  return Success;
}

Connection::~Connection () {
	mysql_close(&mysql);
}

bool Connection::select_db (const char *db) {
  bool suc = !(mysql_select_db(&mysql, db));
  if (throw_exceptions && !suc) throw MysqlBadQuery(error());
  else return suc;
}

bool Connection::reload() {
  bool suc = !mysql_reload(&mysql);
  if (throw_exceptions && !suc) throw MysqlBadQuery(error());
  else return suc;
}

bool Connection::shutdown () {
  bool suc = !(mysql_shutdown(&mysql SHUTDOWN_ARG));
  if (throw_exceptions && !suc) throw MysqlBadQuery(error());
  else return suc;
}

bool Connection::connect (cchar *db, cchar *host, cchar *user, cchar *passwd) {
  locked = true; // mysql.options.my_cnf_file="my";

	mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, "my");

	if (mysql_real_connect(&mysql,host,user,passwd,db, 3306,NULL,0)) {
    locked = false;
    Success = is_connected = true;
  } else {
    locked = false;
    if (throw_exceptions) throw BadQuery(error());
    Success = is_connected = false;
  }
	//	mysql.options.my_cnf_file=0;
  if (!Success) return Success;
  if (db && db[0]) // if db is not empty
    Success = select_db(db);
  return Success;
}

std::string Connection::info () {
  const char *i = mysql_info(&mysql);
  if (!i)
    return std::string();
  else
    return std::string(i);
}

ResNSel Connection::execute(const std::string &str, bool throw_excptns) {
  Success = false;
  if (lock())
    if (throw_excptns) throw BadQuery(error());
    else return ResNSel();
  Success = !mysql_query(&mysql, str.c_str());
  unlock();
  if (!Success)
    if (throw_excptns) throw BadQuery(error());
    else return ResNSel();
  return ResNSel(this);
}

bool Connection::exec(const std::string &str) {
	Success = !mysql_query(&mysql,str.c_str());
	if (!Success && throw_exceptions) throw BadQuery(error());
	return Success;
}

Result Connection::store(const std::string &str, bool throw_excptns) {
  Success = false;

  if (lock()) {
    if (throw_excptns) throw BadQuery(error());
    else return Result();
  }

  Success = !mysql_query(&mysql, str.c_str());
  unlock();

  if (!Success) {
    if (throw_excptns) throw BadQuery(error());
    else return Result();
  }

  MYSQL_RES* res = mysql_store_result(&mysql);
  if (res) return Result(res);
  else return Result();
}

ResUse Connection::use(const std::string &str, bool throw_excptns) {
  Success = false;
  if (lock())
    if (throw_excptns) throw BadQuery(error());
    else return ResUse();
  Success = !mysql_query(&mysql, str.c_str());
  if (!Success)
    if (throw_excptns) throw BadQuery(error());
    else return ResUse();
  return ResUse(mysql_use_result(&mysql), this);
}

<commit_msg>#include platform.h instead of config.h, since config.h is only available on autotools-based systems.<commit_after>#include "connection3.hh"
#include "result3.hh"

#define MYSQLPP_NOT_HEADER
#include "platform.h"

#if defined(HAVE_MYSQL_SHUTDOWN_LEVEL_ARG)
#	define SHUTDOWN_ARG ,SHUTDOWN_DEFAULT
#else
#	define SHUTDOWN_ARG
#endif

Connection::Connection (const char *db, const char *host, const char *user,
			const char *passwd, bool te)
  : throw_exceptions(te), locked(false)
{
	mysql_init(&mysql);
  if (real_connect (db, host, user, passwd,3306,0,60,NULL,0))
	{
    locked = false;
    Success = is_connected = true;
  }
  else
  {
    locked = false; Success = is_connected = false;
    if (throw_exceptions) throw BadQuery(error());
  }
}

Connection::Connection (const char *db, const char *host, const char *user,
			const char *passwd, uint port, my_bool compress,
			unsigned int connect_timeout, bool te,
			const char *socket_name, unsigned client_flag)
  : throw_exceptions(te), locked(false)
{
	mysql_init(&mysql);
  if (real_connect (db, host, user, passwd, port, compress,		connect_timeout,socket_name, client_flag))
  {
    locked = false;
    Success = is_connected = true;
  }
  else
  {
    locked = false; Success = is_connected = false;
    if (throw_exceptions) throw BadQuery(error());
  }
}

bool Connection::real_connect (cchar *db, cchar *host, cchar *user,
			       cchar *passwd, uint port, my_bool compress,
			       unsigned int connect_timeout,
			       const char *socket_name, unsigned int client_flag)
{
  mysql.options.compress = compress;
  mysql.options.connect_timeout=connect_timeout;
  locked = true; //mysql.options.my_cnf_file="my";

	mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, "my");

	if (mysql_real_connect(&mysql,host,user,passwd,db, port,socket_name,client_flag))
  {
    locked = false;
    Success = is_connected = true;
  }
  else
  {
    locked = false; Success = is_connected = false;
    if (throw_exceptions) throw BadQuery(error());
  }
	//	mysql.options.my_cnf_file=0;
  if (!Success) return Success;
  if (db && db[0]) // if db is not empty
    Success = select_db(db);
  return Success;
}

Connection::~Connection () {
	mysql_close(&mysql);
}

bool Connection::select_db (const char *db) {
  bool suc = !(mysql_select_db(&mysql, db));
  if (throw_exceptions && !suc) throw MysqlBadQuery(error());
  else return suc;
}

bool Connection::reload() {
  bool suc = !mysql_reload(&mysql);
  if (throw_exceptions && !suc) throw MysqlBadQuery(error());
  else return suc;
}

bool Connection::shutdown () {
  bool suc = !(mysql_shutdown(&mysql SHUTDOWN_ARG));
  if (throw_exceptions && !suc) throw MysqlBadQuery(error());
  else return suc;
}

bool Connection::connect (cchar *db, cchar *host, cchar *user, cchar *passwd) {
  locked = true; // mysql.options.my_cnf_file="my";

	mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, "my");

	if (mysql_real_connect(&mysql,host,user,passwd,db, 3306,NULL,0)) {
    locked = false;
    Success = is_connected = true;
  } else {
    locked = false;
    if (throw_exceptions) throw BadQuery(error());
    Success = is_connected = false;
  }
	//	mysql.options.my_cnf_file=0;
  if (!Success) return Success;
  if (db && db[0]) // if db is not empty
    Success = select_db(db);
  return Success;
}

std::string Connection::info () {
  const char *i = mysql_info(&mysql);
  if (!i)
    return std::string();
  else
    return std::string(i);
}

ResNSel Connection::execute(const std::string &str, bool throw_excptns) {
  Success = false;
  if (lock())
    if (throw_excptns) throw BadQuery(error());
    else return ResNSel();
  Success = !mysql_query(&mysql, str.c_str());
  unlock();
  if (!Success)
    if (throw_excptns) throw BadQuery(error());
    else return ResNSel();
  return ResNSel(this);
}

bool Connection::exec(const std::string &str) {
	Success = !mysql_query(&mysql,str.c_str());
	if (!Success && throw_exceptions) throw BadQuery(error());
	return Success;
}

Result Connection::store(const std::string &str, bool throw_excptns) {
  Success = false;

  if (lock()) {
    if (throw_excptns) throw BadQuery(error());
    else return Result();
  }

  Success = !mysql_query(&mysql, str.c_str());
  unlock();

  if (!Success) {
    if (throw_excptns) throw BadQuery(error());
    else return Result();
  }

  MYSQL_RES* res = mysql_store_result(&mysql);
  if (res) return Result(res);
  else return Result();
}

ResUse Connection::use(const std::string &str, bool throw_excptns) {
  Success = false;
  if (lock())
    if (throw_excptns) throw BadQuery(error());
    else return ResUse();
  Success = !mysql_query(&mysql, str.c_str());
  if (!Success)
    if (throw_excptns) throw BadQuery(error());
    else return ResUse();
  return ResUse(mysql_use_result(&mysql), this);
}

<|endoftext|>


<commit_before>#include <iostream>
#include <unordered_map>
#include <cstring>
#include <limits>
#include <cmath>
#include <cfloat>

class Tokenizer {
public:
    void updateToken(
            const char *&text) //Указатель будет сдвигаться. Текст - это ссылка на указатель константной char. Не смогу менять то, что внутри, но указатель смогу.
    {
        while (const auto c = *text++) {//Когда встретит 0 - остановится. Приоритет выше у инкремента - прибавим сначала, но разыменуем предыдущий указатель
            switch (c) {
                case ' ':
                    continue;
                case '-':
                    thisToken = Token::Minus;
                    return;
                case '+':
                    thisToken = Token::Plus;
                    return;
                case '*':
                    thisToken = Token::Mul;
                    return;
                case '/':
                    thisToken = Token::Div;
                    return;
                case '(':
                    thisToken = Token::LBrace;
                    return;
                case ')':
                    thisToken = Token::RBrace;
                    return;
            }
            if (c >= '0' && c <= '9') {
                thisToken = Token::Number;
                return;
            }
            if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
                thisToken = Token::Const;
                return;
            }
            throw std::runtime_error("Invalid Symbol"); // Вместо return Token::Invalid;
        }
        thisToken = Token::End;
        return;
    }

    enum class Token {
        Minus,
        Plus,
        Mul,
        Div,
        Number,
        End,
        Const,
        LBrace,
        RBrace
    };

    Token thisToken;
};

template <class T>
struct Parser
{
};
template <class T>
struct NumericTraits
{
};

template<> struct NumericTraits<double>{
    static constexpr double min = std::numeric_limits<double>::min();
    static constexpr double max = std::numeric_limits<double>::max();
};

template <>
struct NumericTraits<int>{
    static constexpr int min = std::numeric_limits<int>::min();
    static constexpr int max = std::numeric_limits<int>::max();
};

template <>
struct NumericTraits<long>{
    static constexpr long min = std::numeric_limits<long>::min();
    static constexpr long max = std::numeric_limits<long>::max();
};

template<>
struct Parser<int>
{
  static bool parse(const char*& text, int& value)
  {
  	long tmp = long(*text - '0');
        while (*(++text) >= '0' && *text <= '9') {
            tmp = tmp * 10 + long(*text - '0');
        }
  if(tmp < NumericTraits<int>::min || tmp > NumericTraits<int>::max)
  	return false;
  value = tmp;
  return true;
  }
  static long bigType;
  static bool checkType(long &a){
  	if(a > NumericTraits<int>::max || a < - NumericTraits<int>::max){
  		return false;
  	}
  	return true;
  }
};

template<>
struct Parser<long>
{
  static bool parse(const char*& text, long& value)
  {
  	long long tmp = (long long)(*text - '0');
        while (*(++text) >= '0' && *text <= '9') {
            tmp = tmp * 10 + (long long)(*text - '0');
        }
  if(tmp < NumericTraits<long>::min || tmp > NumericTraits<long>::max)
  	return false;
  value = tmp;
  return true;
  }
  static long long bigType;
  static bool checkType(long long &a){
  	if(a > NumericTraits<long>::max || a < - NumericTraits<long>::max){
  		return false;
  	}
  	return true;
  }
};

template<>
struct Parser<double>
{
  static bool parse(const char*& text, double& value)
  {
  	long double tmp = (long double)(*text - '0');
        while (*(++text) >= '0' && *text <= '9') {
            tmp = tmp * 10 + (long double)(*text - '0');
        }
        if((*text == '.') && (*(++text) >= '0' || *(text) <= '9')){
        	tmp += (long double)(*text - '0') / 10;
        	int power = -1;
        	while (*(++text) >= '0' && *text <= '9') {
        		--power;
            	tmp +=  (long double)(*text - '0') * pow(10.0, power);
        	}
    	}
  	if(!std::isfinite(tmp)){//Требуется, потому что в случае проверки NumericTraits 0.0 не пройдет проверку.
  		return false;
  	}
  	if(tmp > NumericTraits<double>::max){
  		return false;
  	}
  	value = tmp;
  	return true;
  }

  static bool checkType(long double &a){
  	if(!std::isfinite((double)a)){//Требуется, потому что в случае проверки NumericTraits 0.0 не пройдет проверку.
  		return false;
  	}
  	if(a > NumericTraits<double>::max || a < - NumericTraits<double>::max){
  		return false;
  	}
  	return true;
  }
  static long double bigType;
};

template <class T, class Parser>
class calculator {
public:
    calculator(char *&text){
        expression = text;
    }
    calculator(){

    }

    T calculate(char *&text){
    	expression = text;
    	T result = expr(expression);
        std::cout << result << std::endl;
        return result;
    }

    /*void setExpr(std::string expr){
    	//this->expression = expr;
    	strcpy(this->expression, expr.c_str());
    }*/

private:
    T prim(const char *&text) {
        bool isPositive = true;
        thisToken.updateToken(text);
        --text;
        if (thisToken.thisToken == Tokenizer::Token::Minus) { //Checking if number is positive/negative
            isPositive = false;
            thisToken.updateToken(++text); //Checking what goes after subtraction symbol
            --text;
        }
        if(thisToken.thisToken == Tokenizer::Token::LBrace){//If there are braces - create loop to calculate expr in braces.
            ++text;
            T c = expr(text, true);
            return c * (2 * isPositive - 1);
        }
        if (thisToken.thisToken == Tokenizer::Token::End) {
            return 0;
        }
        if (thisToken.thisToken == Tokenizer::Token::Const){
            int length = 1;
            ++text ;
            while ((*text >= 'A' && *text <= 'Z') || (*text >= 'a' && *text <= 'z')) {
                length += 1;
                ++text;
            }
            std::string var;
            //auto* var = new std::string();
            var.assign(text-length, length);
            return constants.at(var) * (2 * isPositive - 1);
        }
        if (thisToken.thisToken != Tokenizer::Token::Number) {
            throw std::runtime_error("Syntax error");
        }
        T c;
        if(!Parser::parse(text, c))
    		throw std::runtime_error ("Syntax error: number can not be read");

        return c * (2 * isPositive - 1);

    }

    T term(const char *&text) {
        T c = prim(text);
        thisToken.updateToken(text);
        while (thisToken.thisToken == Tokenizer::Token::Mul || thisToken.thisToken == Tokenizer::Token::Div) {

            decltype(Parser::bigType) test = 0.0;
            if (thisToken.thisToken == Tokenizer::Token::Mul) {

            	test = (decltype(Parser::bigType))c * (decltype(Parser::bigType))prim(text);
            	if(Parser::checkType(test)){
            		c = T(test);
            	}else throw std::runtime_error("Result left type limits");

                thisToken.updateToken(text);
            } else {
                T divider = prim(text);
                if (divider) {

                	test = (decltype(Parser::bigType))c / (decltype(Parser::bigType))divider;
            		if(Parser::checkType(test)){
            			c = T(test);
            		}else throw std::runtime_error("Result left type limits");

                    thisToken.updateToken(text);
                } else throw std::runtime_error("Division by zero");
            }
        }
        --text;
        return c;
    }

    T expr(const char *&text, bool fromPrim = false) {
        T c = term(text);
        thisToken.updateToken(text);
        while (thisToken.thisToken != Tokenizer::Token::End && thisToken.thisToken != Tokenizer::Token::RBrace && thisToken.thisToken != Tokenizer::Token::LBrace) {
        	decltype(Parser::bigType) test = 0.0;
            if (thisToken.thisToken == Tokenizer::Token::Plus) {

            	test = (decltype(Parser::bigType))c + (decltype(Parser::bigType))term(text);
            		if(Parser::checkType(test)){
            			c = T(test);
            		}else throw std::runtime_error("Result left type limits");

                thisToken.updateToken(text);
            } else if (thisToken.thisToken == Tokenizer::Token::Minus) {

            	test = (decltype(Parser::bigType))c - (decltype(Parser::bigType))term(text);
            		if(Parser::checkType(test)){
            			c = T(test);
            		}else throw std::runtime_error("Result left type limits");

                thisToken.updateToken(text);
            } else
                throw std::runtime_error("Syntax error");
        }
        if (thisToken.thisToken == Tokenizer::Token::LBrace){
            throw std::runtime_error("Brace syntax error");
        }
        if (thisToken.thisToken != Tokenizer::Token::RBrace || fromPrim){
            return c;
        }
        throw std::runtime_error("Brace syntax error");
    }
    const char* expression;
    std::unordered_map<std::string, double> constants =
            {
                    { "Pi", M_PI },
                    { "e", M_E }
            };
    Tokenizer thisToken;

};

void checkErrors(bool a){
	if(!a)
		std::cout << "error" << std::endl;
	return;
}

bool isEqual(const double &left, const double &right){
	return fabs(left - right) < DBL_EPSILON;
}

int main(int argc, char* argv[]) {

    /*if(argc<2){
        throw std::runtime_error("No input expression");
    }
	const char* expression = argv[1];
    calculator<int,Parser<int>>(expression).calculate();
    *///  I do without args/uncomment and use if needed
    if(argc>1){
    	//const char* expression = argv[1];
    	//calculator<int,Parser<int>>(expression).calculate();
    }

    char* Expr1 = new char[255];
    std::strcpy(Expr1, std::string("3+3").c_str());
    char* Expr2 = new char[255];
    std::strcpy(Expr2, std::string("9/2*2").c_str());
    char* Expr3 = new char[255];
    std::strcpy(Expr3, std::string("Pi*-e").c_str());
    char* Expr4 = new char[255];
    std::strcpy(Expr4, std::string("8*Pi").c_str());

    //DOUBLE

    checkErrors(isEqual(calculator<double,Parser<double>>().calculate(Expr1),(double)6));
    checkErrors(isEqual(calculator<double,Parser<double>>().calculate(Expr2),(double)9));
    checkErrors(isEqual(calculator<double,Parser<double>>().calculate(Expr3),(double)-M_PI*M_E));
    checkErrors(isEqual(calculator<double,Parser<double>>().calculate(Expr4),(double)M_PI*8));

    //INT

    checkErrors(calculator<int,Parser<int>>().calculate(Expr1)==6);
    checkErrors(calculator<int,Parser<int>>().calculate(Expr2)==8);
    checkErrors(calculator<int,Parser<int>>().calculate(Expr3)==-6);
    checkErrors(calculator<int,Parser<int>>().calculate(Expr4)==24);

    //LONG

    checkErrors(calculator<long,Parser<long>>().calculate(Expr1)==6);
    checkErrors(calculator<long,Parser<long>>().calculate(Expr2)==8);
    checkErrors(calculator<long,Parser<long>>().calculate(Expr3)==-6);
    checkErrors(calculator<long,Parser<long>>().calculate(Expr4)==24);

    delete [] Expr1;
    delete [] Expr2;
    delete [] Expr3;
    delete [] Expr4;

    return 0;
}<commit_msg>Fixes<commit_after>#include <iostream>
#include <unordered_map>
#include <cstring>
#include <limits>
#include <cmath>
#include <cfloat>
#include <memory>

class Tokenizer {
public:
    void updateToken(
            const char *&text) //Указатель будет сдвигаться. Текст - это ссылка на указатель константной char. Не смогу менять то, что внутри, но указатель смогу.
    {
        while (const auto c = *text++) {//Когда встретит 0 - остановится. Приоритет выше у инкремента - прибавим сначала, но разыменуем предыдущий указатель
            switch (c) {
                case ' ':
                    continue;
                case '-':
                    thisToken = Token::Minus;
                    return;
                case '+':
                    thisToken = Token::Plus;
                    return;
                case '*':
                    thisToken = Token::Mul;
                    return;
                case '/':
                    thisToken = Token::Div;
                    return;
                case '(':
                    thisToken = Token::LBrace;
                    return;
                case ')':
                    thisToken = Token::RBrace;
                    return;
            }
            if (c >= '0' && c <= '9') {
                thisToken = Token::Number;
                return;
            }
            if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
                thisToken = Token::Const;
                return;
            }
            throw std::runtime_error("Invalid Symbol"); // Вместо return Token::Invalid;
        }
        thisToken = Token::End;
        return;
    }

    enum class Token {
        Minus,
        Plus,
        Mul,
        Div,
        Number,
        End,
        Const,
        LBrace,
        RBrace
    };

    Token thisToken;
};

template <class T>
struct Parser
{
};
template <class T>
struct NumericTraits
{
};

template<> struct NumericTraits<double>{
    static constexpr double min = std::numeric_limits<double>::min();
    static constexpr double max = std::numeric_limits<double>::max();
};

template <>
struct NumericTraits<int>{
    static constexpr int min = std::numeric_limits<int>::min();
    static constexpr int max = std::numeric_limits<int>::max();
};

template <>
struct NumericTraits<long>{
    static constexpr long min = std::numeric_limits<long>::min();
    static constexpr long max = std::numeric_limits<long>::max();
};

template<>
struct Parser<int>
{
  static bool parse(const char*& text, int& value)
  {
  	long tmp = long(*text - '0');
        while (*(++text) >= '0' && *text <= '9') {
            tmp = tmp * 10 + long(*text - '0');
        }
  if(tmp < NumericTraits<int>::min || tmp > NumericTraits<int>::max)
  	return false;
  value = tmp;
  return true;
  }
  static long bigType;
  static bool checkType(long &a){
  	if(a > NumericTraits<int>::max || a < - NumericTraits<int>::max){
  		return false;
  	}
  	return true;
  }
};

template<>
struct Parser<long>
{
  static bool parse(const char*& text, long& value)
  {
  	long long tmp = (long long)(*text - '0');
        while (*(++text) >= '0' && *text <= '9') {
            tmp = tmp * 10 + (long long)(*text - '0');
        }
  if(tmp < NumericTraits<long>::min || tmp > NumericTraits<long>::max)
  	return false;
  value = tmp;
  return true;
  }
  static long long bigType;
  static bool checkType(long long &a){
  	if(a > NumericTraits<long>::max || a < - NumericTraits<long>::max){
  		return false;
  	}
  	return true;
  }
};

template<>
struct Parser<double>
{
  static bool parse(const char*& text, double& value)
  {
  	long double tmp = (long double)(*text - '0');
        while (*(++text) >= '0' && *text <= '9') {
            tmp = tmp * 10 + (long double)(*text - '0');
        }
        if((*text == '.') && (*(++text) >= '0' || *(text) <= '9')){
        	tmp += (long double)(*text - '0') / 10;
        	int power = -1;
        	while (*(++text) >= '0' && *text <= '9') {
        		--power;
            	tmp +=  (long double)(*text - '0') * pow(10.0, power);
        	}
    	}
  	if(!std::isfinite(tmp)){//Требуется, потому что в случае проверки NumericTraits 0.0 не пройдет проверку.
  		return false;
  	}
  	if(tmp > NumericTraits<double>::max){
  		return false;
  	}
  	value = tmp;
  	return true;
  }

  static bool checkType(long double &a){
  	if(!std::isfinite((double)a)){//Требуется, потому что в случае проверки NumericTraits 0.0 не пройдет проверку.
  		return false;
  	}
  	if(a > NumericTraits<double>::max || a < - NumericTraits<double>::max){
  		return false;
  	}
  	return true;
  }
  static long double bigType;
};

template <class T, class Parser>
class calculator {
public:
    calculator(char *&text){
        expression = text;
    }
    calculator(){

    }

    T calculate(char *&text){
    	expression = text;
    	T result = expr(expression);
        return result;
    }

private:
    T prim(const char *&text) {
        bool isPositive = true;
        thisToken.updateToken(text);
        --text;
        if (thisToken.thisToken == Tokenizer::Token::Minus) { //Checking if number is positive/negative
            isPositive = false;
            thisToken.updateToken(++text); //Checking what goes after subtraction symbol
            --text;
        }
        if(thisToken.thisToken == Tokenizer::Token::LBrace){//If there are braces - create loop to calculate expr in braces.
            ++text;
            T c = expr(text, true);
            return c * (2 * isPositive - 1);
        }
        if (thisToken.thisToken == Tokenizer::Token::End) {
            return 0;
        }
        if (thisToken.thisToken == Tokenizer::Token::Const){
            int length = 1;
            ++text ;
            while ((*text >= 'A' && *text <= 'Z') || (*text >= 'a' && *text <= 'z')) {
                length += 1;
                ++text;
            }
            std::string var;
            var.assign(text-length, length);
            return constants.at(var) * (2 * isPositive - 1);
        }
        if (thisToken.thisToken != Tokenizer::Token::Number) {
            throw std::runtime_error("Syntax error");
        }
        T c;
        if(!Parser::parse(text, c))
    		throw std::runtime_error ("Syntax error: number can not be read");

        return c * (2 * isPositive - 1);

    }

    T term(const char *&text) {
        T c = prim(text);
        thisToken.updateToken(text);
        while (thisToken.thisToken == Tokenizer::Token::Mul || thisToken.thisToken == Tokenizer::Token::Div) {

            decltype(Parser::bigType) test = 0.0;
            if (thisToken.thisToken == Tokenizer::Token::Mul) {

            	test = (decltype(Parser::bigType))c * (decltype(Parser::bigType))prim(text);
            	if(Parser::checkType(test)){
            		c = T(test);
            	}else throw std::runtime_error("Result left type limits");

                thisToken.updateToken(text);
            } else {
                T divider = prim(text);
                if (divider) {

                	test = (decltype(Parser::bigType))c / (decltype(Parser::bigType))divider;
            		if(Parser::checkType(test)){
            			c = T(test);
            		}else throw std::runtime_error("Result left type limits");

                    thisToken.updateToken(text);
                } else throw std::runtime_error("Division by zero");
            }
        }
        --text;
        return c;
    }

    T expr(const char *&text, bool fromPrim = false) {
        T c = term(text);
        thisToken.updateToken(text);
        while (thisToken.thisToken != Tokenizer::Token::End && thisToken.thisToken != Tokenizer::Token::RBrace && thisToken.thisToken != Tokenizer::Token::LBrace) {
        	decltype(Parser::bigType) test = 0.0;
            if (thisToken.thisToken == Tokenizer::Token::Plus) {

            	test = (decltype(Parser::bigType))c + (decltype(Parser::bigType))term(text);
            		if(Parser::checkType(test)){
            			c = T(test);
            		}else throw std::runtime_error("Result left type limits");

                thisToken.updateToken(text);
            } else if (thisToken.thisToken == Tokenizer::Token::Minus) {

            	test = (decltype(Parser::bigType))c - (decltype(Parser::bigType))term(text);
            		if(Parser::checkType(test)){
            			c = T(test);
            		}else throw std::runtime_error("Result left type limits");

                thisToken.updateToken(text);
            } else
                throw std::runtime_error("Syntax error");
        }
        if (thisToken.thisToken == Tokenizer::Token::LBrace){
            throw std::runtime_error("Brace syntax error");
        }
        if (thisToken.thisToken != Tokenizer::Token::RBrace || fromPrim){
            return c;
        }
        throw std::runtime_error("Brace syntax error");
    }
    const char* expression;
    std::unordered_map<std::string, double> constants =
            {
                    { "Pi", M_PI },
                    { "e", M_E }
            };
    Tokenizer thisToken;

};

void checkErrors(bool a){
	if(!a)
		std::cout << "error" << std::endl;
	return;
}

bool isEqual(const double &left, const double &right){
	return fabs(left - right) < DBL_EPSILON;
}

int main(int argc, char* argv[]) {

    char* Expr1 = new char[255];
    std::strcpy(Expr1, std::string("3+3").c_str());
    char* Expr2 = new char[255];
    std::strcpy(Expr2, std::string("9/2*2").c_str());
    char* Expr3 = new char[255];
    std::strcpy(Expr3, std::string("Pi*-e").c_str());
    char* Expr4 = new char[255];
    std::strcpy(Expr4, std::string("8*Pi").c_str());

    //DOUBLE

    checkErrors(isEqual(calculator<double,Parser<double>>().calculate(Expr1),(double)6));
    checkErrors(isEqual(calculator<double,Parser<double>>().calculate(Expr2),(double)9));
    checkErrors(isEqual(calculator<double,Parser<double>>().calculate(Expr3),(double)-M_PI*M_E));
    checkErrors(isEqual(calculator<double,Parser<double>>().calculate(Expr4),(double)M_PI*8));

    //INT

    checkErrors(calculator<int,Parser<int>>().calculate(Expr1)==6);
    checkErrors(calculator<int,Parser<int>>().calculate(Expr2)==8);
    checkErrors(calculator<int,Parser<int>>().calculate(Expr3)==-6);
    checkErrors(calculator<int,Parser<int>>().calculate(Expr4)==24);

    //LONG

    checkErrors(calculator<long,Parser<long>>().calculate(Expr1)==6);
    checkErrors(calculator<long,Parser<long>>().calculate(Expr2)==8);
    checkErrors(calculator<long,Parser<long>>().calculate(Expr3)==-6);
    checkErrors(calculator<long,Parser<long>>().calculate(Expr4)==24);

    delete [] Expr1;
    delete [] Expr2;
    delete [] Expr3;
    delete [] Expr4;

    std::cout<< "If no errors above - it works right" << std::endl;

    return 0;
}
<|endoftext|>