<commit_before>#include "IRPrinter.h"
#include "IROperator.h"
#include "IR.h"

#include <iostream>
#include <sstream>

namespace Halide {

using std::ostream;
using std::endl;
using std::vector;
using std::string;
using std::ostringstream;

ostream &operator<<(ostream &out, Type type) {
    switch (type.t) {
    case Type::Int:
        out << "int";
        break;
    case Type::UInt:
        out << "uint";
        break;
    case Type::Float:
        out << "float";
        break;
    default:
        assert(false && "Malformed type");
    }
    out << type.bits;
    if (type.width > 1) out << 'x' << type.width;
    return out;
}

ostream &operator<<(ostream &stream, Expr ir) {
    if (!ir.defined()) {
        stream << "(undefined)";
    } else {
        Internal::IRPrinter p(stream);
        p.print(ir);
    }
    return stream;
}

namespace Internal {

void IRPrinter::test() {
    Type i32 = Int(32);
    Type f32 = Float(32);
    Expr x = Variable::make(Int(32), "x");
    Expr y = Variable::make(Int(32), "y");
    ostringstream expr_source;
    expr_source << (x + 3) * (y / 2 + 17);
    assert(expr_source.str() == "((x + 3)*((y/2) + 17))");

    Stmt store = Store::make("buf", (x * 17) / (x - 3), y - 1);
    Stmt for_loop = For::make("x", -2, y + 2, For::Parallel, store);
    vector<Expr> args(1); args[0] = x % 3;
    Expr call = Call::make(i32, "buf", args, Call::Extern);
    Stmt store2 = Store::make("out", call + 1, x);
    Stmt for_loop2 = For::make("x", 0, y, For::Vectorized , store2);
    Stmt pipeline = Pipeline::make("buf", for_loop, Stmt(), for_loop2);
    Stmt assertion = AssertStmt::make(y > 3, "y is greater than 3");
    Stmt block = Block::make(assertion, pipeline);
    Stmt let_stmt = LetStmt::make("y", 17, block);
    Stmt allocate = Allocate::make("buf", f32, 1023, let_stmt);

    ostringstream source;
    source << allocate;
    std::string correct_source = \
        "allocate buf[float32 * 1023]\n"
        "let y = 17\n"
        "assert((y > 3), \"y is greater than 3\")\n"
        "produce buf {\n"
        "  parallel (x, -2, (y + 2)) {\n"
        "    buf[(y - 1)] = ((x*17)/(x - 3))\n"
        "  }\n"
        "}\n"
        "vectorized (x, 0, y) {\n"
        "  out[x] = (buf((x % 3)) + 1)\n"
        "}\n";

    if (source.str() != correct_source) {
        std::cout << "Correct output:" << std::endl << correct_source;
        std::cout << "Actual output:" << std::endl << source.str();
        assert(false);
    }
    std::cout << "IRPrinter test passed" << std::endl;
}

ostream &operator<<(ostream &out, const For::ForType &type) {
    switch (type) {
    case For::Serial:
        out << "for";
        break;
    case For::Parallel:
        out << "parallel";
        break;
    case For::Unrolled:
        out << "unrolled";
        break;
    case For::Vectorized:
        out << "vectorized";
        break;
    default:
        assert(false && "Malformed for type");
    }
    return out;
}

ostream &operator<<(ostream &stream, Stmt ir) {
    if (!ir.defined()) {
        stream << "(undefined)" << std::endl;
    } else {
        Internal::IRPrinter p(stream);
        p.print(ir);
    }
    return stream;
}

IRPrinter::IRPrinter(ostream &s) : stream(s), indent(0) {
    s.setf(std::ios::fixed, std::ios::floatfield);
}

void IRPrinter::print(Expr ir) {
    ir.accept(this);
}

void IRPrinter::print(Stmt ir) {
    ir.accept(this);
}

void IRPrinter::do_indent() {
    for (int i = 0; i < indent; i++) stream << ' ';
}

void IRPrinter::visit(const IntImm *op) {
    stream << op->value;
}

void IRPrinter::visit(const FloatImm *op) {
    stream << op->value << 'f';
}

void IRPrinter::visit(const Cast *op) {
    stream << op->type << '(';
    print(op->value);
    stream << ')';
}

void IRPrinter::visit(const Variable *op) {
    // omit the type
    // stream << op->name << "." << op->type;
    stream << op->name;
}

void IRPrinter::visit(const Add *op) {
    stream << '(';
    print(op->a);
    stream << " + ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Sub *op) {
    stream << '(';
    print(op->a);
    stream << " - ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Mul *op) {
    stream << '(';
    print(op->a);
    stream << "*";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Div *op) {
    stream << '(';
    print(op->a);
    stream << "/";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Mod *op) {
    stream << '(';
    print(op->a);
    stream << " % ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Min *op) {
    stream << "min(";
    print(op->a);
    stream << ", ";
    print(op->b);
    stream << ")";
}

void IRPrinter::visit(const Max *op) {
    stream << "max(";
    print(op->a);
    stream << ", ";
    print(op->b);
    stream << ")";
}

void IRPrinter::visit(const EQ *op) {
    stream << '(';
    print(op->a);
    stream << " == ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const NE *op) {
    stream << '(';
    print(op->a);
    stream << " != ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const LT *op) {
    stream << '(';
    print(op->a);
    stream << " < ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const LE *op) {
    stream << '(';
    print(op->a);
    stream << " <= ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const GT *op) {
    stream << '(';
    print(op->a);
    stream << " > ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const GE *op) {
    stream << '(';
    print(op->a);
    stream << " >= ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const And *op) {
    stream << '(';
    print(op->a);
    stream << " && ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Or *op) {
    stream << '(';
    print(op->a);
    stream << " || ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Not *op) {
    stream << '!';
    print(op->a);
}

void IRPrinter::visit(const Select *op) {
    stream << "select(";
    print(op->condition);
    stream << ", ";
    print(op->true_value);
    stream << ", ";
    print(op->false_value);
    stream << ")";
}

void IRPrinter::visit(const Load *op) {
    stream << op->name << "[";
    print(op->index);
    stream << "]";
}

void IRPrinter::visit(const Ramp *op) {
    stream << "ramp(";
    print(op->base);
    stream << ", ";
    print(op->stride);
    stream << ", " << op->width << ")";
}

void IRPrinter::visit(const Broadcast *op) {
    stream << "x" << op->width << "(";
    print(op->value);
    stream << ")";
}

void IRPrinter::visit(const Call *op) {
    stream << op->name << "(";
    for (size_t i = 0; i < op->args.size(); i++) {
        print(op->args[i]);
        if (i < op->args.size() - 1) {
            stream << ", ";
        }
    }
    stream << ")";
}

void IRPrinter::visit(const Let *op) {
    stream << "(let " << op->name << " = ";
    print(op->value);
    stream << " in ";
    print(op->body);
    stream << ")";
}

void IRPrinter::visit(const LetStmt *op) {
    do_indent();
    stream << "let " << op->name << " = ";
    print(op->value);
    stream << endl;

    print(op->body);
}

void IRPrinter::visit(const PrintStmt *op) {
    do_indent();
    stream << "print(" << op->prefix;
    for (size_t i = 0; i < op->args.size(); i++) {
        stream << ", ";
        print(op->args[i]);
    }
    stream << ")" << endl;
}

void IRPrinter::visit(const AssertStmt *op) {
    do_indent();
    stream << "assert(";
    print(op->condition);
    stream << ", \"" << op->message << "\")" << endl;
}

void IRPrinter::visit(const Pipeline *op) {

    do_indent();
    stream << "produce " << op->name << " {" << endl;
    indent += 2;
    print(op->produce);
    indent -= 2;

    if (op->update.defined()) {
        do_indent();
        stream << "} update " << op->name << " {" << endl;
        indent += 2;
        print(op->update);
        indent -= 2;
    }

    do_indent();
    stream << "}\n";

    print(op->consume);

}

void IRPrinter::visit(const For *op) {

    do_indent();
    stream << op->for_type << " (" << op->name << ", ";
    print(op->min);
    stream << ", ";
    print(op->extent);
    stream << ") {" << endl;

    indent += 2;
    print(op->body);
    indent -= 2;

    do_indent();
    stream << "}" << endl;
}

void IRPrinter::visit(const Store *op) {
    do_indent();
    stream << op->name << "[";
    print(op->index);
    stream << "] = ";
    print(op->value);
    stream << endl;
}

void IRPrinter::visit(const Provide *op) {
    do_indent();
    stream << op->name << "(";
    for (size_t i = 0; i < op->args.size(); i++) {
        print(op->args[i]);
        if (i < op->args.size() - 1) stream << ", ";
    }
    stream << ") = ";
    print(op->value);
    stream << endl;
}

void IRPrinter::visit(const Allocate *op) {
    do_indent();
    stream << "allocate " << op->name << "[" << op->type << " * ";
    print(op->size);
    stream << "]" << endl;
    print(op->body);
}

void IRPrinter::visit(const Free *op) {
    do_indent();
    stream << "free " << op->name << endl;
}

void IRPrinter::visit(const Realize *op) {
    do_indent();
    stream << "realize " << op->name << "(";
    for (size_t i = 0; i < op->bounds.size(); i++) {
        stream << "[";
        print(op->bounds[i].min);
        stream << ", ";
        print(op->bounds[i].extent);
        stream << "]";
        if (i < op->bounds.size() - 1) stream << ", ";
    }
    stream << ") {" << endl;

    indent += 2;
    print(op->body);
    indent -= 2;

    do_indent();
    stream << "}" << endl;
}

void IRPrinter::visit(const Block *op) {
    print(op->first);
    if (op->rest.defined()) print(op->rest);
}

}}
<commit_msg>Remove default cases from switch statements.<commit_after>#include "IRPrinter.h"
#include "IROperator.h"
#include "IR.h"

#include <iostream>
#include <sstream>

namespace Halide {

using std::ostream;
using std::endl;
using std::vector;
using std::string;
using std::ostringstream;

ostream &operator<<(ostream &out, Type type) {
    switch (type.t) {
    case Type::Int:
        out << "int";
        break;
    case Type::UInt:
        out << "uint";
        break;
    case Type::Float:
        out << "float";
        break;
    }
    out << type.bits;
    if (type.width > 1) out << 'x' << type.width;
    return out;
}

ostream &operator<<(ostream &stream, Expr ir) {
    if (!ir.defined()) {
        stream << "(undefined)";
    } else {
        Internal::IRPrinter p(stream);
        p.print(ir);
    }
    return stream;
}

namespace Internal {

void IRPrinter::test() {
    Type i32 = Int(32);
    Type f32 = Float(32);
    Expr x = Variable::make(Int(32), "x");
    Expr y = Variable::make(Int(32), "y");
    ostringstream expr_source;
    expr_source << (x + 3) * (y / 2 + 17);
    assert(expr_source.str() == "((x + 3)*((y/2) + 17))");

    Stmt store = Store::make("buf", (x * 17) / (x - 3), y - 1);
    Stmt for_loop = For::make("x", -2, y + 2, For::Parallel, store);
    vector<Expr> args(1); args[0] = x % 3;
    Expr call = Call::make(i32, "buf", args, Call::Extern);
    Stmt store2 = Store::make("out", call + 1, x);
    Stmt for_loop2 = For::make("x", 0, y, For::Vectorized , store2);
    Stmt pipeline = Pipeline::make("buf", for_loop, Stmt(), for_loop2);
    Stmt assertion = AssertStmt::make(y > 3, "y is greater than 3");
    Stmt block = Block::make(assertion, pipeline);
    Stmt let_stmt = LetStmt::make("y", 17, block);
    Stmt allocate = Allocate::make("buf", f32, 1023, let_stmt);

    ostringstream source;
    source << allocate;
    std::string correct_source = \
        "allocate buf[float32 * 1023]\n"
        "let y = 17\n"
        "assert((y > 3), \"y is greater than 3\")\n"
        "produce buf {\n"
        "  parallel (x, -2, (y + 2)) {\n"
        "    buf[(y - 1)] = ((x*17)/(x - 3))\n"
        "  }\n"
        "}\n"
        "vectorized (x, 0, y) {\n"
        "  out[x] = (buf((x % 3)) + 1)\n"
        "}\n";

    if (source.str() != correct_source) {
        std::cout << "Correct output:" << std::endl << correct_source;
        std::cout << "Actual output:" << std::endl << source.str();
        assert(false);
    }
    std::cout << "IRPrinter test passed" << std::endl;
}

ostream &operator<<(ostream &out, const For::ForType &type) {
    switch (type) {
    case For::Serial:
        out << "for";
        break;
    case For::Parallel:
        out << "parallel";
        break;
    case For::Unrolled:
        out << "unrolled";
        break;
    case For::Vectorized:
        out << "vectorized";
        break;
    }
    return out;
}

ostream &operator<<(ostream &stream, Stmt ir) {
    if (!ir.defined()) {
        stream << "(undefined)" << std::endl;
    } else {
        Internal::IRPrinter p(stream);
        p.print(ir);
    }
    return stream;
}

IRPrinter::IRPrinter(ostream &s) : stream(s), indent(0) {
    s.setf(std::ios::fixed, std::ios::floatfield);
}

void IRPrinter::print(Expr ir) {
    ir.accept(this);
}

void IRPrinter::print(Stmt ir) {
    ir.accept(this);
}

void IRPrinter::do_indent() {
    for (int i = 0; i < indent; i++) stream << ' ';
}

void IRPrinter::visit(const IntImm *op) {
    stream << op->value;
}

void IRPrinter::visit(const FloatImm *op) {
    stream << op->value << 'f';
}

void IRPrinter::visit(const Cast *op) {
    stream << op->type << '(';
    print(op->value);
    stream << ')';
}

void IRPrinter::visit(const Variable *op) {
    // omit the type
    // stream << op->name << "." << op->type;
    stream << op->name;
}

void IRPrinter::visit(const Add *op) {
    stream << '(';
    print(op->a);
    stream << " + ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Sub *op) {
    stream << '(';
    print(op->a);
    stream << " - ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Mul *op) {
    stream << '(';
    print(op->a);
    stream << "*";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Div *op) {
    stream << '(';
    print(op->a);
    stream << "/";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Mod *op) {
    stream << '(';
    print(op->a);
    stream << " % ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Min *op) {
    stream << "min(";
    print(op->a);
    stream << ", ";
    print(op->b);
    stream << ")";
}

void IRPrinter::visit(const Max *op) {
    stream << "max(";
    print(op->a);
    stream << ", ";
    print(op->b);
    stream << ")";
}

void IRPrinter::visit(const EQ *op) {
    stream << '(';
    print(op->a);
    stream << " == ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const NE *op) {
    stream << '(';
    print(op->a);
    stream << " != ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const LT *op) {
    stream << '(';
    print(op->a);
    stream << " < ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const LE *op) {
    stream << '(';
    print(op->a);
    stream << " <= ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const GT *op) {
    stream << '(';
    print(op->a);
    stream << " > ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const GE *op) {
    stream << '(';
    print(op->a);
    stream << " >= ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const And *op) {
    stream << '(';
    print(op->a);
    stream << " && ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Or *op) {
    stream << '(';
    print(op->a);
    stream << " || ";
    print(op->b);
    stream << ')';
}

void IRPrinter::visit(const Not *op) {
    stream << '!';
    print(op->a);
}

void IRPrinter::visit(const Select *op) {
    stream << "select(";
    print(op->condition);
    stream << ", ";
    print(op->true_value);
    stream << ", ";
    print(op->false_value);
    stream << ")";
}

void IRPrinter::visit(const Load *op) {
    stream << op->name << "[";
    print(op->index);
    stream << "]";
}

void IRPrinter::visit(const Ramp *op) {
    stream << "ramp(";
    print(op->base);
    stream << ", ";
    print(op->stride);
    stream << ", " << op->width << ")";
}

void IRPrinter::visit(const Broadcast *op) {
    stream << "x" << op->width << "(";
    print(op->value);
    stream << ")";
}

void IRPrinter::visit(const Call *op) {
    stream << op->name << "(";
    for (size_t i = 0; i < op->args.size(); i++) {
        print(op->args[i]);
        if (i < op->args.size() - 1) {
            stream << ", ";
        }
    }
    stream << ")";
}

void IRPrinter::visit(const Let *op) {
    stream << "(let " << op->name << " = ";
    print(op->value);
    stream << " in ";
    print(op->body);
    stream << ")";
}

void IRPrinter::visit(const LetStmt *op) {
    do_indent();
    stream << "let " << op->name << " = ";
    print(op->value);
    stream << endl;

    print(op->body);
}

void IRPrinter::visit(const PrintStmt *op) {
    do_indent();
    stream << "print(" << op->prefix;
    for (size_t i = 0; i < op->args.size(); i++) {
        stream << ", ";
        print(op->args[i]);
    }
    stream << ")" << endl;
}

void IRPrinter::visit(const AssertStmt *op) {
    do_indent();
    stream << "assert(";
    print(op->condition);
    stream << ", \"" << op->message << "\")" << endl;
}

void IRPrinter::visit(const Pipeline *op) {

    do_indent();
    stream << "produce " << op->name << " {" << endl;
    indent += 2;
    print(op->produce);
    indent -= 2;

    if (op->update.defined()) {
        do_indent();
        stream << "} update " << op->name << " {" << endl;
        indent += 2;
        print(op->update);
        indent -= 2;
    }

    do_indent();
    stream << "}\n";

    print(op->consume);

}

void IRPrinter::visit(const For *op) {

    do_indent();
    stream << op->for_type << " (" << op->name << ", ";
    print(op->min);
    stream << ", ";
    print(op->extent);
    stream << ") {" << endl;

    indent += 2;
    print(op->body);
    indent -= 2;

    do_indent();
    stream << "}" << endl;
}

void IRPrinter::visit(const Store *op) {
    do_indent();
    stream << op->name << "[";
    print(op->index);
    stream << "] = ";
    print(op->value);
    stream << endl;
}

void IRPrinter::visit(const Provide *op) {
    do_indent();
    stream << op->name << "(";
    for (size_t i = 0; i < op->args.size(); i++) {
        print(op->args[i]);
        if (i < op->args.size() - 1) stream << ", ";
    }
    stream << ") = ";
    print(op->value);
    stream << endl;
}

void IRPrinter::visit(const Allocate *op) {
    do_indent();
    stream << "allocate " << op->name << "[" << op->type << " * ";
    print(op->size);
    stream << "]" << endl;
    print(op->body);
}

void IRPrinter::visit(const Free *op) {
    do_indent();
    stream << "free " << op->name << endl;
}

void IRPrinter::visit(const Realize *op) {
    do_indent();
    stream << "realize " << op->name << "(";
    for (size_t i = 0; i < op->bounds.size(); i++) {
        stream << "[";
        print(op->bounds[i].min);
        stream << ", ";
        print(op->bounds[i].extent);
        stream << "]";
        if (i < op->bounds.size() - 1) stream << ", ";
    }
    stream << ") {" << endl;

    indent += 2;
    print(op->body);
    indent -= 2;

    do_indent();
    stream << "}" << endl;
}

void IRPrinter::visit(const Block *op) {
    print(op->first);
    if (op->rest.defined()) print(op->rest);
}

}}
<|endoftext|>


<commit_before>void MakeVZERORecoParam(AliRecoParam::EventSpecie_t default=AliRecoParam::kLowMult) {
//========================================================================
//
// Steering macro for VZERO reconstruction parameters
//
// Author: Brigitte Cheynis
//
//========================================================================

  const char* macroname = "MakeVZERORecoParam.C";

  // Activate CDB storage and load geometry from CDB
  AliCDBManager* cdb = AliCDBManager::Instance();
  if(!cdb->IsDefaultStorageSet()) cdb->SetDefaultStorage("local://OCDB");

  TObjArray *recoParamArray = new TObjArray();

  {
    AliVZERORecoParam * vzeroRecoParam = new AliVZERORecoParam;
    vzeroRecoParam->SetEventSpecie(AliRecoParam::kCosmic);
    recoParamArray->AddLast(vzeroRecoParam);
  }
  {
    AliVZERORecoParam * vzeroRecoParam = new AliVZERORecoParam;
    vzeroRecoParam->SetEventSpecie(AliRecoParam::kLowMult);
    recoParamArray->AddLast(vzeroRecoParam);
  }
  {
    AliVZERORecoParam * vzeroRecoParam = new AliVZERORecoParam;
    vzeroRecoParam->SetNPreClocks(6);
    vzeroRecoParam->SetEventSpecie(AliRecoParam::kHighMult);
    recoParamArray->AddLast(vzeroRecoParam);
  }

  // Set the default
  Bool_t defaultIsSet = kFALSE;
  for(Int_t i =0; i < recoParamArray->GetEntriesFast(); i++) {
    AliDetectorRecoParam *param = (AliDetectorRecoParam *)recoParamArray->UncheckedAt(i);
    if (!param) continue;
    if (default & param->GetEventSpecie()) {
      param->SetAsDefault();
      defaultIsSet = kTRUE;
    }
  }

  if (!defaultIsSet) {
    Error(macroname,"The default reconstruction parameters are not set! Exiting...");
    return;
  }

  // save in CDB storage
  AliCDBMetaData *md= new AliCDBMetaData();
  md->SetResponsible("Brigitte Cheynis");
  md->SetComment("Reconstruction parameters for VZERO");
  md->SetAliRootVersion(gSystem->Getenv("ARVERSION"));
  md->SetBeamPeriod(0);
  AliCDBId id("VZERO/Calib/RecoParam",0,AliCDBRunRange::Infinity());
  cdb->GetDefaultStorage()->Put(recoParamArray,id, md);

  return;
}
<commit_msg>Reducing the search window used to find the max in the ADC samples. Needed because of the dense filling scheme in 2011<commit_after>void MakeVZERORecoParam(AliRecoParam::EventSpecie_t default=AliRecoParam::kLowMult) {
//========================================================================
//
// Steering macro for VZERO reconstruction parameters
//
// Author: Brigitte Cheynis
//
//========================================================================

  const char* macroname = "MakeVZERORecoParam.C";

  // Activate CDB storage and load geometry from CDB
  AliCDBManager* cdb = AliCDBManager::Instance();
  if(!cdb->IsDefaultStorageSet()) cdb->SetDefaultStorage("local://OCDB");

  TObjArray *recoParamArray = new TObjArray();

  {
    AliVZERORecoParam * vzeroRecoParam = new AliVZERORecoParam;
    vzeroRecoParam->SetEventSpecie(AliRecoParam::kCosmic);
    recoParamArray->AddLast(vzeroRecoParam);
  }
  {
    AliVZERORecoParam * vzeroRecoParam = new AliVZERORecoParam;
    // the following two settings are needed to high lumi runs in 2011
    vzeroRecoParam->SetStartClock(9);
    vzeroRecoParam->SetEndClock(11);
    vzeroRecoParam->SetEventSpecie(AliRecoParam::kLowMult);
    recoParamArray->AddLast(vzeroRecoParam);
  }
  {
    AliVZERORecoParam * vzeroRecoParam = new AliVZERORecoParam;
    vzeroRecoParam->SetNPreClocks(6);
    vzeroRecoParam->SetEventSpecie(AliRecoParam::kHighMult);
    recoParamArray->AddLast(vzeroRecoParam);
  }

  // Set the default
  Bool_t defaultIsSet = kFALSE;
  for(Int_t i =0; i < recoParamArray->GetEntriesFast(); i++) {
    AliDetectorRecoParam *param = (AliDetectorRecoParam *)recoParamArray->UncheckedAt(i);
    if (!param) continue;
    if (default & param->GetEventSpecie()) {
      param->SetAsDefault();
      defaultIsSet = kTRUE;
    }
  }

  if (!defaultIsSet) {
    Error(macroname,"The default reconstruction parameters are not set! Exiting...");
    return;
  }

  // save in CDB storage
  AliCDBMetaData *md= new AliCDBMetaData();
  md->SetResponsible("Brigitte Cheynis");
  md->SetComment("Reconstruction parameters for VZERO");
  md->SetAliRootVersion(gSystem->Getenv("ARVERSION"));
  md->SetBeamPeriod(0);
  AliCDBId id("VZERO/Calib/RecoParam",0,AliCDBRunRange::Infinity());
  cdb->GetDefaultStorage()->Put(recoParamArray,id, md);

  return;
}
<|endoftext|>


<commit_before>#include <boost/version.hpp>

#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/vertex_converters.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_factory.hpp>

#if BOOST_VERSION >= 104700
#include <mapnik/util/geometry_to_wkb.hpp>
#include <mapnik/util/geometry_to_wkt.hpp>
#include <mapnik/util/geometry_to_svg.hpp>
#endif

#include <boost/detail/lightweight_test.hpp>
#include <iostream>

struct output_geometry_backend
{
    output_geometry_backend(boost::ptr_vector<mapnik::geometry_type> & paths, mapnik::eGeomType type)
        : paths_(paths),
          type_(type) {}

    template <typename T>
    void add_path(T & path)
    {
        mapnik::vertex2d vtx(mapnik::vertex2d::no_init);
        path.rewind(0);
        std::auto_ptr<mapnik::geometry_type> geom_ptr(new mapnik::geometry_type(type_));

        while ((vtx.cmd = path.vertex(&vtx.x, &vtx.y)) != mapnik::SEG_END)
        {
            //std::cerr << vtx.x << "," << vtx.y << "   cmd=" << vtx.cmd << std::endl;
            geom_ptr->push_vertex(vtx.x, vtx.y, (mapnik::CommandType)vtx.cmd);
        }
        paths_.push_back(geom_ptr);
    }
    boost::ptr_vector<mapnik::geometry_type> &  paths_;
    mapnik::eGeomType type_;
};

boost::optional<std::string> linestring_bbox_clipping(mapnik::box2d<double> bbox,
                                                      std::string wkt_in)
{
    using namespace mapnik;
    agg::trans_affine tr;
    projection src;
    projection dst;
    proj_transform prj_trans(src,dst);
    line_symbolizer sym;
    CoordTransform t(bbox.width(),bbox.height(), bbox);
    boost::ptr_vector<mapnik::geometry_type> output_paths;
    output_geometry_backend backend(output_paths, mapnik::LineString);

    typedef boost::mpl::vector<clip_line_tag> conv_types;
    vertex_converter<box2d<double>, output_geometry_backend, line_symbolizer,
                     CoordTransform, proj_transform, agg::trans_affine, conv_types>
        converter(bbox, backend, sym, t, prj_trans, tr, 1.0);

    converter.template set<clip_line_tag>();

    boost::ptr_vector<geometry_type> p;
    if (!mapnik::from_wkt(wkt_in , p))
    {
        throw std::runtime_error("Failed to parse WKT");
    }

    BOOST_FOREACH( geometry_type & geom, p)
    {
        converter.apply(geom);
    }

    std::string wkt_out;
    if (mapnik::util::to_wkt(wkt_out, output_paths))
    {
        return boost::optional<std::string>(wkt_out);
    }

    return boost::optional<std::string>();
}

boost::optional<std::string> polygon_bbox_clipping(mapnik::box2d<double> bbox,
                                                   std::string wkt_in)
{
    using namespace mapnik;
    agg::trans_affine tr;
    projection src;
    projection dst;
    proj_transform prj_trans(src,dst);
    polygon_symbolizer sym;
    CoordTransform t(bbox.width(),bbox.height(), bbox);
    boost::ptr_vector<mapnik::geometry_type> output_paths;
    output_geometry_backend backend(output_paths, mapnik::Polygon);

    typedef boost::mpl::vector<clip_poly_tag> conv_types;
    vertex_converter<box2d<double>, output_geometry_backend, polygon_symbolizer,
                     CoordTransform, proj_transform, agg::trans_affine, conv_types>
        converter(bbox, backend, sym, t, prj_trans, tr, 1.0);

    converter.template set<clip_poly_tag>();

    boost::ptr_vector<geometry_type> p;
    if (!mapnik::from_wkt(wkt_in , p))
    {
        throw std::runtime_error("Failed to parse WKT");
    }

    BOOST_FOREACH( geometry_type & geom, p)
    {
        converter.apply(geom);
    }

    std::string wkt_out;
    if (mapnik::util::to_wkt(wkt_out, output_paths))
    {
        return boost::optional<std::string>(wkt_out);
    }

    return boost::optional<std::string>();
}

int main( int, char*[] )
{
    // LineString/bbox clipping
    {
        std::string wkt_in("LineString(0 0,200 200)");
        boost::optional<std::string> result = linestring_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result,std::string("LineString(50 50,150 150)"));
    }
    // Polygon/bbox clipping
#if 0
    // these tests will fail
    {
        std::string wkt_in("Polygon((50 50,150 50,150 150,50 150,50 50))");
        boost::optional<std::string> result = polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result,std::string("Polygon((50 50,150 50,150 150,50 150,50 50))"));
    }

    {
        std::string wkt_in("Polygon((60 60,140 60,140 160,60 140,60 60))");
        boost::optional<std::string> result = polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result,std::string("Polygon((60 60,140 60,140 160,60 140,60 60))"));
    }

    {
        std::string wkt_in("Polygon((0 0,10 0,10 10,0 10,0 0))");
        boost::optional<std::string> result = polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result, std::string("GeometryCollection EMPTY"));
    }
#endif
    {
        std::string wkt_in("Polygon((0 0,100 200,200 0,0 0 ))");
        boost::optional<std::string> result = polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result,std::string("Polygon((50 50,50 100,75 150,125 150,150 100,150 50,50 50))"));
    }

    if (!::boost::detail::test_errors())
    {
        std::clog << "C++ geometry conversions: \x1b[1;32m✓ \x1b[0m\n";
#if BOOST_VERSION >= 104600
        ::boost::detail::report_errors_remind().called_report_errors_function = true;
#endif
    }
    else
    {
        return ::boost::report_errors();
    }
}
<commit_msg>+ fix #1700<commit_after>#include <boost/version.hpp>

#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/vertex_converters.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_factory.hpp>

#if BOOST_VERSION >= 104700
#include <mapnik/util/geometry_to_wkb.hpp>
#include <mapnik/util/geometry_to_wkt.hpp>
#include <mapnik/util/geometry_to_svg.hpp>
#endif

#include <boost/detail/lightweight_test.hpp>
#include <iostream>

struct output_geometry_backend
{
    output_geometry_backend(boost::ptr_vector<mapnik::geometry_type> & paths, mapnik::eGeomType type)
        : paths_(paths),
          type_(type) {}

    template <typename T>
    void add_path(T & path)
    {
        mapnik::vertex2d vtx(mapnik::vertex2d::no_init);
        path.rewind(0);
        std::auto_ptr<mapnik::geometry_type> geom_ptr(new mapnik::geometry_type(type_));

        while ((vtx.cmd = path.vertex(&vtx.x, &vtx.y)) != mapnik::SEG_END)
        {
            //std::cerr << vtx.x << "," << vtx.y << "   cmd=" << vtx.cmd << std::endl;
            geom_ptr->push_vertex(vtx.x, vtx.y, (mapnik::CommandType)vtx.cmd);
        }
        paths_.push_back(geom_ptr);
    }
    boost::ptr_vector<mapnik::geometry_type> &  paths_;
    mapnik::eGeomType type_;
};

boost::optional<std::string> linestring_bbox_clipping(mapnik::box2d<double> bbox,
                                                      std::string wkt_in)
{
    using namespace mapnik;
    agg::trans_affine tr;
    projection src;
    projection dst;
    proj_transform prj_trans(src,dst);
    line_symbolizer sym;
    CoordTransform t(bbox.width(),bbox.height(), bbox);
    boost::ptr_vector<mapnik::geometry_type> output_paths;
    output_geometry_backend backend(output_paths, mapnik::LineString);

    typedef boost::mpl::vector<clip_line_tag> conv_types;
    vertex_converter<box2d<double>, output_geometry_backend, line_symbolizer,
                     CoordTransform, proj_transform, agg::trans_affine, conv_types>
        converter(bbox, backend, sym, t, prj_trans, tr, 1.0);

    converter.set<clip_line_tag>();

    boost::ptr_vector<geometry_type> p;
    if (!mapnik::from_wkt(wkt_in , p))
    {
        throw std::runtime_error("Failed to parse WKT");
    }

    BOOST_FOREACH( geometry_type & geom, p)
    {
        converter.apply(geom);
    }

    std::string wkt_out;
    if (mapnik::util::to_wkt(wkt_out, output_paths))
    {
        return boost::optional<std::string>(wkt_out);
    }

    return boost::optional<std::string>();
}

boost::optional<std::string> polygon_bbox_clipping(mapnik::box2d<double> bbox,
                                                   std::string wkt_in)
{
    using namespace mapnik;
    agg::trans_affine tr;
    projection src;
    projection dst;
    proj_transform prj_trans(src,dst);
    polygon_symbolizer sym;
    CoordTransform t(bbox.width(),bbox.height(), bbox);
    boost::ptr_vector<mapnik::geometry_type> output_paths;
    output_geometry_backend backend(output_paths, mapnik::Polygon);

    typedef boost::mpl::vector<clip_poly_tag> conv_types;
    vertex_converter<box2d<double>, output_geometry_backend, polygon_symbolizer,
                     CoordTransform, proj_transform, agg::trans_affine, conv_types>
        converter(bbox, backend, sym, t, prj_trans, tr, 1.0);

    converter.set<clip_poly_tag>();

    boost::ptr_vector<geometry_type> p;
    if (!mapnik::from_wkt(wkt_in , p))
    {
        throw std::runtime_error("Failed to parse WKT");
    }

    BOOST_FOREACH( geometry_type & geom, p)
    {
        converter.apply(geom);
    }

    std::string wkt_out;
    if (mapnik::util::to_wkt(wkt_out, output_paths))
    {
        return boost::optional<std::string>(wkt_out);
    }

    return boost::optional<std::string>();
}

int main( int, char*[] )
{
    // LineString/bbox clipping
    {
        std::string wkt_in("LineString(0 0,200 200)");
        boost::optional<std::string> result = linestring_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result,std::string("LineString(50 50,150 150)"));
    }
    // Polygon/bbox clipping
#if 0
    // these tests will fail
    {
        std::string wkt_in("Polygon((50 50,150 50,150 150,50 150,50 50))");
        boost::optional<std::string> result = polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result,std::string("Polygon((50 50,150 50,150 150,50 150,50 50))"));
    }

    {
        std::string wkt_in("Polygon((60 60,140 60,140 160,60 140,60 60))");
        boost::optional<std::string> result = polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result,std::string("Polygon((60 60,140 60,140 160,60 140,60 60))"));
    }

    {
        std::string wkt_in("Polygon((0 0,10 0,10 10,0 10,0 0))");
        boost::optional<std::string> result = polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result, std::string("GeometryCollection EMPTY"));
    }
#endif
    {
        std::string wkt_in("Polygon((0 0,100 200,200 0,0 0 ))");
        boost::optional<std::string> result = polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
        BOOST_TEST(result);
        BOOST_TEST_EQ(*result,std::string("Polygon((50 50,50 100,75 150,125 150,150 100,150 50,50 50))"));
    }

    if (!::boost::detail::test_errors())
    {
        std::clog << "C++ geometry conversions: \x1b[1;32m✓ \x1b[0m\n";
#if BOOST_VERSION >= 104600
        ::boost::detail::report_errors_remind().called_report_errors_function = true;
#endif
    }
    else
    {
        return ::boost::report_errors();
    }
}
<|endoftext|>


<commit_before>/**
 * @file       BlynkDebug.cpp
 * @author     Volodymyr Shymanskyy
 * @license    This project is released under the MIT License (MIT)
 * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
 * @date       Jan 2015
 * @brief      Debug utilities for Arduino
 */
#include "BlynkDebug.h"

size_t BlynkFreeRam()
{
    return 0;
}

void BlynkReset()
{
    System.reset();
    for(;;);
}

void BlynkFatal()
{
    BlynkReset();
    for(;;);
}
<commit_msg>Update BlynkDebug.cpp<commit_after>/**
 * @file       BlynkDebug.cpp
 * @author     Volodymyr Shymanskyy
 * @license    This project is released under the MIT License (MIT)
 * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
 * @date       Jan 2015
 * @brief      Debug utilities for Arduino
 */
#include "BlynkDebug.h"
#include "application.h"

size_t BlynkFreeRam()
{
    return 0;
}

void BlynkReset()
{
    System.reset();
    for(;;);
}

void BlynkFatal()
{
    BlynkReset();
    for(;;);
}
<|endoftext|>


<commit_before>#include "Precompiled.h"
#include "VulkanDevice.h"
#include <cassert>
#include "VLog.h"

using namespace vulkan;

class VulkanDevice::impl
{
public:
	impl(std::shared_ptr<VulkanPhysicalDevice> device) : PhysicalDevice(device)
	{
		auto queue_props = PhysicalDevice->getQueueFamilyProperties();

		auto found = false;
		for (unsigned int i = 0; i < queue_props.size(); i++)
		{
			if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
			{
				queue_info.queueFamilyIndex = i;
				found = true;
				log() << "Found gpu " << i << " with queue with VK_QUEUE_GRAPHICS_BIT\n";
				break;
			}
		}
		assert(found);

		float queue_priorities[1] = { 0.0 };
		queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
		queue_info.pNext = nullptr;
		queue_info.queueCount = 1;
		queue_info.pQueuePriorities = queue_priorities;

		device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
		device_info.pNext = nullptr;
		device_info.queueCreateInfoCount = 1;
		device_info.pQueueCreateInfos = &queue_info;
		device_info.enabledExtensionCount = 0;
		device_info.ppEnabledExtensionNames = nullptr;
		device_info.enabledLayerCount = 0;
		device_info.ppEnabledLayerNames = nullptr;
		device_info.pEnabledFeatures = nullptr;

		auto res = vkCreateDevice(PhysicalDevice->getPhysicalDevice(), &device_info, NULL, &LogicalDevice);
		assert(res == VK_SUCCESS);

		log() << "Created a logical device\n";
	}

	~impl()
	{
		vkDestroyDevice(LogicalDevice, nullptr);
	}

	VkDevice LogicalDevice;
	std::shared_ptr<VulkanPhysicalDevice> PhysicalDevice;

	VkDeviceQueueCreateInfo queue_info = {};
	VkDeviceCreateInfo device_info = {};
};

VulkanDevice::VulkanDevice(std::shared_ptr<VulkanPhysicalDevice> device)
{
	pimpl = std::make_unique<impl>(device);
}

VulkanDevice::~VulkanDevice()
{
	// empty
}
<commit_msg>minor clean up<commit_after>#include "Precompiled.h"
#include "VulkanDevice.h"
#include <cassert>
#include "VLog.h"

using namespace vulkan;

class VulkanDevice::impl
{
public:
	explicit impl(std::shared_ptr<VulkanPhysicalDevice> device) : PhysicalDevice(device)
	{
		auto queue_props = PhysicalDevice->getQueueFamilyProperties();

		auto found = false;
		for (unsigned int i = 0; i < queue_props.size(); i++)
		{
			if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
			{
				queue_info.queueFamilyIndex = i;
				found = true;
				log() << "Found gpu " << i << " with queue with VK_QUEUE_GRAPHICS_BIT\n";
				break;
			}
		}
		assert(found);

		float queue_priorities[1] = { 0.0 };
		queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
		queue_info.pNext = nullptr;
		queue_info.queueCount = 1;
		queue_info.pQueuePriorities = queue_priorities;

		device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
		device_info.pNext = nullptr;
		device_info.queueCreateInfoCount = 1;
		device_info.pQueueCreateInfos = &queue_info;
		device_info.enabledExtensionCount = 0;
		device_info.ppEnabledExtensionNames = nullptr;
		device_info.enabledLayerCount = 0;
		device_info.ppEnabledLayerNames = nullptr;
		device_info.pEnabledFeatures = nullptr;

		auto res = vkCreateDevice(PhysicalDevice->getPhysicalDevice(), &device_info, nullptr, &LogicalDevice);
		assert(res == VK_SUCCESS);

		log() << "Created a logical device\n";
	}

	~impl()
	{
		vkDestroyDevice(LogicalDevice, nullptr);
	}

	VkDevice LogicalDevice;
	std::shared_ptr<VulkanPhysicalDevice> PhysicalDevice;

	VkDeviceQueueCreateInfo queue_info = {};
	VkDeviceCreateInfo device_info = {};
};

VulkanDevice::VulkanDevice(std::shared_ptr<VulkanPhysicalDevice> device)
{
	pimpl = std::make_unique<impl>(device);
}

VulkanDevice::~VulkanDevice()
{
	// empty
}
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file Indicator.cxx
 ** Defines the style of indicators which are text decorations such as underlining.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <vector>
#include <map>

#include "Platform.h"

#include "Scintilla.h"
#include "XPM.h"
#include "Indicator.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static PRectangle PixelGridAlign(const PRectangle &rc) {
	// Move left and right side to nearest pixel to avoid blurry visuals
	return PRectangle(int(rc.left + 0.5), rc.top, int(rc.right + 0.5), rc.bottom);
}

void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine) {
	surface->PenColour(fore);
	int ymid = (rc.bottom + rc.top) / 2;
	if (style == INDIC_SQUIGGLE) {
		surface->MoveTo(rc.left, rc.top);
		int x = rc.left + 2;
		int y = 2;
		while (x < rc.right) {
			surface->LineTo(x, rc.top + y);
			x += 2;
			y = 2 - y;
		}
		surface->LineTo(rc.right, rc.top + y);	// Finish the line
	} else if (style == INDIC_SQUIGGLEPIXMAP) {
		PRectangle rcSquiggle = PixelGridAlign(rc);

		int width = Platform::Minimum(4000, rcSquiggle.Width());
		RGBAImage image(width, 3, 1.0, 0);
		enum { alphaFull = 0xff, alphaSide = 0x2f, alphaSide2=0x5f };
		for (int x = 0; x < width; x++) {
			if (x%2) {
				// Two halfway columns have a full pixel in middle flanked by light pixels
				image.SetPixel(x, 0, fore, alphaSide);
				image.SetPixel(x, 1, fore, alphaFull);
				image.SetPixel(x, 2, fore, alphaSide);
			} else {
				// Extreme columns have a full pixel at bottom or top and a mid-tone pixel in centre
				image.SetPixel(x, (x%4) ? 0 : 2, fore, alphaFull);
				image.SetPixel(x, 1, fore, alphaSide2);
			}
		}
		surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels());
	} else if (style == INDIC_SQUIGGLELOW) {
		surface->MoveTo(rc.left, rc.top);
		int x = rc.left + 3;
		int y = 0;
		while (x < rc.right) {
			surface->LineTo(x-1, rc.top + y);
			y = 1 - y;
        	surface->LineTo(x, rc.top + y);
			x += 3;
		}
		surface->LineTo(rc.right, rc.top + y);	// Finish the line
	} else if (style == INDIC_TT) {
		surface->MoveTo(rc.left, ymid);
		int x = rc.left + 5;
		while (x < rc.right) {
			surface->LineTo(x, ymid);
			surface->MoveTo(x-3, ymid);
			surface->LineTo(x-3, ymid+2);
			x++;
			surface->MoveTo(x, ymid);
			x += 5;
		}
		surface->LineTo(rc.right, ymid);	// Finish the line
		if (x - 3 <= rc.right) {
			surface->MoveTo(x-3, ymid);
			surface->LineTo(x-3, ymid+2);
		}
	} else if (style == INDIC_DIAGONAL) {
		int x = rc.left;
		while (x < rc.right) {
			surface->MoveTo(x, rc.top+2);
			int endX = x+3;
			int endY = rc.top - 1;
			if (endX > rc.right) {
				endY += endX - rc.right;
				endX = rc.right;
			}
			surface->LineTo(endX, endY);
			x += 4;
		}
	} else if (style == INDIC_STRIKE) {
		surface->MoveTo(rc.left, rc.top - 4);
		surface->LineTo(rc.right, rc.top - 4);
	} else if (style == INDIC_HIDDEN) {
		// Draw nothing
	} else if (style == INDIC_BOX) {
		surface->MoveTo(rc.left, ymid+1);
		surface->LineTo(rc.right, ymid+1);
		surface->LineTo(rc.right, rcLine.top+1);
		surface->LineTo(rc.left, rcLine.top+1);
		surface->LineTo(rc.left, ymid+1);
	} else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
		PRectangle rcBox = rcLine;
		rcBox.top = rcLine.top + 1;
		rcBox.left = rc.left;
		rcBox.right = rc.right;
		surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore, fillAlpha, fore, outlineAlpha, 0);
	} else if (style == INDIC_DOTBOX) {
		PRectangle rcBox = PixelGridAlign(rc);
		rcBox.top = rcLine.top + 1;
		rcBox.bottom = rcLine.bottom;
		// Cap width at 4000 to avoid large allocations when mistakes made
		int width = Platform::Minimum(rcBox.Width(), 4000);
		RGBAImage image(width, rcBox.Height(), 1.0, 0);
		// Draw horizontal lines top and bottom
		for (int x=0; x<width; x++) {
			for (int y=0; y<rcBox.Height(); y += rcBox.Height()-1) {
				image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha);
			}
		}
		// Draw vertical lines left and right
		for (int y=1; y<rcBox.Height(); y++) {
			for (int x=0; x<width; x += width-1) {
				image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha);
			}
		}
		surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels());
	} else if (style == INDIC_DASH) {
		int x = rc.left;
		while (x < rc.right) {
			surface->MoveTo(x, ymid);
			surface->LineTo(Platform::Minimum(x + 4, rc.right), ymid);
			x += 7;
		}
	} else if (style == INDIC_DOTS) {
		int x = rc.left;
		while (x < rc.right) {
			PRectangle rcDot(x, ymid, x+1, ymid+1);
			surface->FillRectangle(rcDot, fore);
			x += 2;
		}
	} else {	// Either INDIC_PLAIN or unknown
		surface->MoveTo(rc.left, ymid);
		surface->LineTo(rc.right, ymid);
	}
}

<commit_msg>Avoid poor drawing at right of INDIC_SQUIGGLE.<commit_after>// Scintilla source code edit control
/** @file Indicator.cxx
 ** Defines the style of indicators which are text decorations such as underlining.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <vector>
#include <map>

#include "Platform.h"

#include "Scintilla.h"
#include "XPM.h"
#include "Indicator.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static PRectangle PixelGridAlign(const PRectangle &rc) {
	// Move left and right side to nearest pixel to avoid blurry visuals
	return PRectangle(int(rc.left + 0.5), rc.top, int(rc.right + 0.5), rc.bottom);
}

void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine) {
	surface->PenColour(fore);
	int ymid = (rc.bottom + rc.top) / 2;
	if (style == INDIC_SQUIGGLE) {
		int x = int(rc.left+0.5);
		int xLast = int(rc.right+0.5);
		int y = 0;
		surface->MoveTo(x, rc.top + y);
		while (x < xLast) {
			if ((x + 2) > xLast) {
				if (xLast > x)
					y = 1;
				x = xLast;
			} else {
				x += 2;
				y = 2 - y;
			}
			surface->LineTo(x, rc.top + y);
		}
	} else if (style == INDIC_SQUIGGLEPIXMAP) {
		PRectangle rcSquiggle = PixelGridAlign(rc);

		int width = Platform::Minimum(4000, rcSquiggle.Width());
		RGBAImage image(width, 3, 1.0, 0);
		enum { alphaFull = 0xff, alphaSide = 0x2f, alphaSide2=0x5f };
		for (int x = 0; x < width; x++) {
			if (x%2) {
				// Two halfway columns have a full pixel in middle flanked by light pixels
				image.SetPixel(x, 0, fore, alphaSide);
				image.SetPixel(x, 1, fore, alphaFull);
				image.SetPixel(x, 2, fore, alphaSide);
			} else {
				// Extreme columns have a full pixel at bottom or top and a mid-tone pixel in centre
				image.SetPixel(x, (x%4) ? 0 : 2, fore, alphaFull);
				image.SetPixel(x, 1, fore, alphaSide2);
			}
		}
		surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels());
	} else if (style == INDIC_SQUIGGLELOW) {
		surface->MoveTo(rc.left, rc.top);
		int x = rc.left + 3;
		int y = 0;
		while (x < rc.right) {
			surface->LineTo(x-1, rc.top + y);
			y = 1 - y;
        	surface->LineTo(x, rc.top + y);
			x += 3;
		}
		surface->LineTo(rc.right, rc.top + y);	// Finish the line
	} else if (style == INDIC_TT) {
		surface->MoveTo(rc.left, ymid);
		int x = rc.left + 5;
		while (x < rc.right) {
			surface->LineTo(x, ymid);
			surface->MoveTo(x-3, ymid);
			surface->LineTo(x-3, ymid+2);
			x++;
			surface->MoveTo(x, ymid);
			x += 5;
		}
		surface->LineTo(rc.right, ymid);	// Finish the line
		if (x - 3 <= rc.right) {
			surface->MoveTo(x-3, ymid);
			surface->LineTo(x-3, ymid+2);
		}
	} else if (style == INDIC_DIAGONAL) {
		int x = rc.left;
		while (x < rc.right) {
			surface->MoveTo(x, rc.top+2);
			int endX = x+3;
			int endY = rc.top - 1;
			if (endX > rc.right) {
				endY += endX - rc.right;
				endX = rc.right;
			}
			surface->LineTo(endX, endY);
			x += 4;
		}
	} else if (style == INDIC_STRIKE) {
		surface->MoveTo(rc.left, rc.top - 4);
		surface->LineTo(rc.right, rc.top - 4);
	} else if (style == INDIC_HIDDEN) {
		// Draw nothing
	} else if (style == INDIC_BOX) {
		surface->MoveTo(rc.left, ymid+1);
		surface->LineTo(rc.right, ymid+1);
		surface->LineTo(rc.right, rcLine.top+1);
		surface->LineTo(rc.left, rcLine.top+1);
		surface->LineTo(rc.left, ymid+1);
	} else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
		PRectangle rcBox = rcLine;
		rcBox.top = rcLine.top + 1;
		rcBox.left = rc.left;
		rcBox.right = rc.right;
		surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore, fillAlpha, fore, outlineAlpha, 0);
	} else if (style == INDIC_DOTBOX) {
		PRectangle rcBox = PixelGridAlign(rc);
		rcBox.top = rcLine.top + 1;
		rcBox.bottom = rcLine.bottom;
		// Cap width at 4000 to avoid large allocations when mistakes made
		int width = Platform::Minimum(rcBox.Width(), 4000);
		RGBAImage image(width, rcBox.Height(), 1.0, 0);
		// Draw horizontal lines top and bottom
		for (int x=0; x<width; x++) {
			for (int y=0; y<rcBox.Height(); y += rcBox.Height()-1) {
				image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha);
			}
		}
		// Draw vertical lines left and right
		for (int y=1; y<rcBox.Height(); y++) {
			for (int x=0; x<width; x += width-1) {
				image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha);
			}
		}
		surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels());
	} else if (style == INDIC_DASH) {
		int x = rc.left;
		while (x < rc.right) {
			surface->MoveTo(x, ymid);
			surface->LineTo(Platform::Minimum(x + 4, rc.right), ymid);
			x += 7;
		}
	} else if (style == INDIC_DOTS) {
		int x = rc.left;
		while (x < rc.right) {
			PRectangle rcDot(x, ymid, x+1, ymid+1);
			surface->FillRectangle(rcDot, fore);
			x += 2;
		}
	} else {	// Either INDIC_PLAIN or unknown
		surface->MoveTo(rc.left, ymid);
		surface->LineTo(rc.right, ymid);
	}
}

<|endoftext|>


<commit_before>#ifndef PANGOLINDISPLAY_HPP
#define PANGOLINDISPLAY_HPP

#include <imp/core/size.hpp>
#include <imp/core/image.hpp>
#include <pangolin/display.h>

#include <imp/cu_core/cu_image_gpu.cuh>

namespace imp
{

//------------------------------------------------------------------------------
inline pangolin::View& setupPangolinView(
    const imp::Size2u& sz,
    const std::string& title = "-")
{
  // Create OpenGL window in single line
  pangolin::CreateWindowAndBind("Lena", sz.width(), sz.height());

  if (glewInit() != GLEW_OK )
  {
    LOG(ERROR) << "Unable to initialize GLEW." << std::endl;
  }

  glEnable(GL_DEPTH_TEST); // 3D Mouse handler requires depth testing to be enabled
  //! @todo (MWE) set OpenGL parameters... which glHint / glEnable options do we need?

  pangolin::View& container = pangolin::CreateDisplay()
      .SetBounds(0, 1.0f, 0, 1.0f);

  return container;
}

//------------------------------------------------------------------------------
inline void setupPangolinViewLayout(
    pangolin::View& container,
    int num_tiles=1, std::vector<float> aspect={})
{
  container.SetLayout(pangolin::LayoutEqual);
  for (int i=0; i<num_tiles; ++i)
  {
    pangolin::View& v = pangolin::CreateDisplay();
    if(static_cast<int>(aspect.size())>i)
    {
      v.SetAspect(aspect.at(i));
    }
    container.AddDisplay(v);
  }

  //! @todo (MWE) register keypresses, etc.
}

//------------------------------------------------------------------------------
inline void imshow(const imp::Image8uC1& im, const std::string& title="-")
{
  pangolin::View& container = imp::setupPangolinView(im.size(), title);
  imp::setupPangolinViewLayout(container, 1, {(float)im.width()/im.height()});
  pangolin::GlTexture tex8(im.width(), im.height(), GL_LUMINANCE8);

  while(!pangolin::ShouldQuit())
  {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);

    if (container[0].IsShown())
    {
      container[0].Activate();
      tex8.Upload(im.data(), GL_LUMINANCE, GL_UNSIGNED_BYTE);
      tex8.RenderToViewportFlipY();
    }
    pangolin::FinishFrame();
  }
}

//------------------------------------------------------------------------------
inline void imshow(const imp::cu::Image8uC1& im, const std::string& title="-")
{
  pangolin::View& container = imp::setupPangolinView(im.size(), title);
  imp::setupPangolinViewLayout(container, 1, {(float)im.width()/im.height()});

  container[0].SetDrawFunction

  pangolin::GlTexture tex8(im.width(), im.height(), GL_LUMINANCE8);

  while(!pangolin::ShouldQuit())
  {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);

    if (container[0].IsShown())
    {
      container[0].Activate();
      tex8.Upload(im.data(), GL_LUMINANCE, GL_UNSIGNED_BYTE);
      tex8.RenderToViewportFlipY();
    }
    pangolin::FinishFrame();
  }
}

////==============================================================================
//class PangolinDisplay
//{
//public:
//  PangolinDisplay();
//  ~PangolinDisplay();
//};

} // namespace imp

#endif // PANGOLINDISPLAY_HPP
<commit_msg>cuda image display still a todo<commit_after>#ifndef PANGOLINDISPLAY_HPP
#define PANGOLINDISPLAY_HPP

#include <imp/core/size.hpp>
#include <imp/core/image.hpp>
#include <pangolin/display.h>

#include <imp/cu_core/cu_image_gpu.cuh>

namespace imp
{

//------------------------------------------------------------------------------
inline pangolin::View& setupPangolinCudaView(
    const imp::Size2u& sz,
    const std::string& title = "-")
{
  pangolin::View& container = pangolin::setupPangolinView(sz, title);
      .SetBounds(0, 1.0f, 0, 1.0f);

  // TODO

  return container;
}

//------------------------------------------------------------------------------
inline pangolin::View& setupPangolinView(
    const imp::Size2u& sz,
    const std::string& title = "-")
{
  // Create OpenGL window in single line
  pangolin::CreateWindowAndBind(title, sz.width(), sz.height());

  if (glewInit() != GLEW_OK )
  {
    LOG(ERROR) << "Unable to initialize GLEW." << std::endl;
  }

  glEnable(GL_DEPTH_TEST); // 3D Mouse handler requires depth testing to be enabled
  //! @todo (MWE) set OpenGL parameters... which glHint / glEnable options do we need?

  pangolin::View& container = pangolin::CreateDisplay()
      .SetBounds(0, 1.0f, 0, 1.0f);

  return container;
}

//------------------------------------------------------------------------------
inline void setupPangolinViewLayout(
    pangolin::View& container,
    int num_tiles=1, std::vector<float> aspect={})
{
  container.SetLayout(pangolin::LayoutEqual);
  for (int i=0; i<num_tiles; ++i)
  {
    pangolin::View& v = pangolin::CreateDisplay();
    if(static_cast<int>(aspect.size())>i)
    {
      v.SetAspect(aspect.at(i));
    }
    container.AddDisplay(v);
  }

  //! @todo (MWE) register keypresses, etc.
}

//------------------------------------------------------------------------------
inline void imshow(const imp::Image8uC1& im, const std::string& title="-")
{
  pangolin::View& container = imp::setupPangolinView(im.size(), title);
  imp::setupPangolinViewLayout(container, 1, {(float)im.width()/im.height()});
  pangolin::GlTexture tex8(im.width(), im.height(), GL_LUMINANCE8);

  while(!pangolin::ShouldQuit())
  {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);

    if (container[0].IsShown())
    {
      container[0].Activate();
      tex8.Upload(im.data(), GL_LUMINANCE, GL_UNSIGNED_BYTE);
      tex8.RenderToViewportFlipY();
    }
    pangolin::FinishFrame();
  }
}

////------------------------------------------------------------------------------
//inline void imshow(const imp::cu::ImageGpu8uC1& im, const std::string& title="-")
//{
//  pangolin::View& container = imp::setupPangolinView(im.size(), title);
//  imp::setupPangolinViewLayout(container, 1, {(float)im.width()/im.height()});

//  container[0].SetDrawFunction

//}

////==============================================================================
//class PangolinDisplay
//{
//public:
//  PangolinDisplay();
//  ~PangolinDisplay();
//};

} // namespace imp

#endif // PANGOLINDISPLAY_HPP
<|endoftext|>


<commit_before>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <algorithm>
#include <limits>

#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_POSIX)
#include <sys/mman.h>
#include <unistd.h>
#endif

using std::nothrow;
using std::numeric_limits;

namespace {

// This function acts as a compiler optimization barrier. We use it to
// prevent the compiler from making an expression a compile-time constant.
// We also use it so that the compiler doesn't discard certain return values
// as something we don't need (see the comment with calloc below).
template <typename Type>
Type HideValueFromCompiler(volatile Type value) {
  return value;
}

// Check that we can not allocate a memory range that cannot be indexed
// via an int. This is used to mitigate vulnerabilities in libraries that use
// int instead of size_t.
// See crbug.com/169327.

// - NO_TCMALLOC because we only patched tcmalloc
// - ADDRESS_SANITIZER because it has its own memory allocator
// - IOS does not seem to honor nothrow in new properly
// - OS_MACOSX does not use tcmalloc
#if !defined(NO_TCMALLOC) && !defined(ADDRESS_SANITIZER) && \
    !defined(OS_IOS) && !defined(OS_MACOSX)
  #define ALLOC_TEST(function) function
#else
  #define ALLOC_TEST(function) DISABLED_##function
#endif

// TODO(jln): switch to std::numeric_limits<int>::max() when we switch to
// C++11.
const size_t kTooBigAllocSize = INT_MAX;

// Detect runtime TCMalloc bypasses.
bool IsTcMallocBypassed() {
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
  // This should detect a TCMalloc bypass from Valgrind.
  char* g_slice = getenv("G_SLICE");
  if (g_slice && !strcmp(g_slice, "always-malloc"))
    return true;
#endif
  return false;
}

// Fake test that allow to know the state of TCMalloc by looking at bots.
TEST(SecurityTest, ALLOC_TEST(IsTCMallocDynamicallyBypassed)) {
  printf("Malloc is dynamically bypassed: %s\n",
         IsTcMallocBypassed() ? "yes." : "no.");
}

TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsMalloc)) {
  if (!IsTcMallocBypassed()) {
    scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>(
        HideValueFromCompiler(malloc(kTooBigAllocSize))));
    ASSERT_TRUE(!ptr);
  }
}

TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsCalloc)) {
  if (!IsTcMallocBypassed()) {
    scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>(
        HideValueFromCompiler(calloc(kTooBigAllocSize, 1))));
    ASSERT_TRUE(!ptr);
  }
}

TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsRealloc)) {
  if (!IsTcMallocBypassed()) {
    char* orig_ptr = static_cast<char*>(malloc(1));
    ASSERT_TRUE(orig_ptr);
    scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>(
        HideValueFromCompiler(realloc(orig_ptr, kTooBigAllocSize))));
    ASSERT_TRUE(!ptr);
    // If realloc() did not succeed, we need to free orig_ptr.
    free(orig_ptr);
  }
}

typedef struct {
  char large_array[kTooBigAllocSize];
} VeryLargeStruct;

TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsNew)) {
  if (!IsTcMallocBypassed()) {
    scoped_ptr<VeryLargeStruct> ptr(
        HideValueFromCompiler(new (nothrow) VeryLargeStruct));
    ASSERT_TRUE(!ptr);
  }
}

TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsNewArray)) {
  if (!IsTcMallocBypassed()) {
    scoped_ptr<char[]> ptr(
        HideValueFromCompiler(new (nothrow) char[kTooBigAllocSize]));
    ASSERT_TRUE(!ptr);
  }
}

// The tests bellow check for overflows in new[] and calloc().

#if defined(OS_IOS) || defined(OS_WIN)
  #define DISABLE_ON_IOS_AND_WIN(function) DISABLED_##function
#else
  #define DISABLE_ON_IOS_AND_WIN(function) function
#endif

#if defined(ADDRESS_SANITIZER)
  #define DISABLE_ON_ASAN(function) DISABLED_##function
#else
  #define DISABLE_ON_ASAN(function) function
#endif

// There are platforms where these tests are known to fail. We would like to
// be able to easily check the status on the bots, but marking tests as
// FAILS_ is too clunky.
void OverflowTestsSoftExpectTrue(bool overflow_detected) {
  if (!overflow_detected) {
#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX)
    // Sadly, on Linux, Android, and OSX we don't have a good story yet. Don't
    // fail the test, but report.
    printf("Platform has overflow: %s\n",
           !overflow_detected ? "yes." : "no.");
#else
    // Otherwise, fail the test. (Note: EXPECT are ok in subfunctions, ASSERT
    // aren't).
    EXPECT_TRUE(overflow_detected);
#endif
  }
}

// TODO(jln): crbug.com/174947 This can't even compile on Win64.
#if !(defined(OS_WIN) && defined(ARCH_CPU_X86_64))

// Test array[TooBig][X] and array[X][TooBig] allocations for int overflows.
// IOS doesn't honor nothrow, so disable the test there.
// Disable on Windows, we suspect some are failing because of it.
TEST(SecurityTest, DISABLE_ON_IOS_AND_WIN(NewOverflow)) {
  const size_t kArraySize = 4096;
  // We want something "dynamic" here, so that the compiler doesn't
  // immediately reject crazy arrays.
  const size_t kDynamicArraySize = HideValueFromCompiler(kArraySize);
  // numeric_limits are still not constexpr until we switch to C++11, so we
  // use an ugly cast.
  const size_t kMaxSizeT = ~static_cast<size_t>(0);
  ASSERT_EQ(numeric_limits<size_t>::max(), kMaxSizeT);
  const size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
  const size_t kDynamicArraySize2 = HideValueFromCompiler(kArraySize2);
  {
    scoped_ptr<char[][kArraySize]> array_pointer(new (nothrow)
        char[kDynamicArraySize2][kArraySize]);
    OverflowTestsSoftExpectTrue(!array_pointer);
  }
  {
    scoped_ptr<char[][kArraySize2]> array_pointer(new (nothrow)
        char[kDynamicArraySize][kArraySize2]);
    OverflowTestsSoftExpectTrue(!array_pointer);
  }
}
#endif

// Test if calloc() can overflow. Disable on ASAN for now since the
// overflow seems present there.
TEST(SecurityTest, DISABLE_ON_ASAN(CallocOverflow)) {
  const size_t kArraySize = 4096;
  const size_t kMaxSizeT = numeric_limits<size_t>::max();
  const size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
  {
    scoped_ptr<char> array_pointer(
        static_cast<char*>(calloc(kArraySize, kArraySize2)));
    // We need the call to HideValueFromCompiler(): we have seen LLVM
    // optimize away the call to calloc() entirely and assume
    // the pointer to not be NULL.
    EXPECT_TRUE(HideValueFromCompiler(array_pointer.get()) == NULL);
  }
  {
    scoped_ptr<char> array_pointer(
        static_cast<char*>(calloc(kArraySize2, kArraySize)));
    // We need the call to HideValueFromCompiler(): we have seen LLVM
    // optimize away the call to calloc() entirely and assume
    // the pointer to not be NULL.
    EXPECT_TRUE(HideValueFromCompiler(array_pointer.get()) == NULL);
  }
}

#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__x86_64__)
// Useful for debugging.
void PrintProcSelfMaps() {
  int fd = open("/proc/self/maps", O_RDONLY);
  file_util::ScopedFD fd_closer(&fd);
  ASSERT_GE(fd, 0);
  char buffer[1<<13];
  int ret;
  ret = read(fd, buffer, sizeof(buffer) - 1);
  ASSERT_GT(ret, 0);
  buffer[ret - 1] = 0;
  fprintf(stdout, "%s\n", buffer);
}

// Check if ptr1 and ptr2 are separated by less than size chars.
bool ArePointersToSameArea(void* ptr1, void* ptr2, size_t size) {
  ptrdiff_t ptr_diff = reinterpret_cast<char*>(std::max(ptr1, ptr2)) -
                       reinterpret_cast<char*>(std::min(ptr1, ptr2));
  return static_cast<size_t>(ptr_diff) <= size;
}

// Check if TCMalloc uses an underlying random memory allocator.
TEST(SecurityTest, ALLOC_TEST(RandomMemoryAllocations)) {
  if (IsTcMallocBypassed())
    return;
  size_t kPageSize = 4096;  // We support x86_64 only.
  // Check that malloc() returns an address that is neither the kernel's
  // un-hinted mmap area, nor the current brk() area. The first malloc() may
  // not be at a random address because TCMalloc will first exhaust any memory
  // that it has allocated early on, before starting the sophisticated
  // allocators.
  void* default_mmap_heap_address =
      mmap(0, kPageSize, PROT_READ|PROT_WRITE,
           MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  ASSERT_NE(default_mmap_heap_address,
            static_cast<void*>(MAP_FAILED));
  ASSERT_EQ(munmap(default_mmap_heap_address, kPageSize), 0);
  void* brk_heap_address = sbrk(0);
  ASSERT_NE(brk_heap_address, reinterpret_cast<void*>(-1));
  ASSERT_TRUE(brk_heap_address != NULL);
  // 1 MB should get us past what TCMalloc pre-allocated before initializing
  // the sophisticated allocators.
  size_t kAllocSize = 1<<20;
  scoped_ptr<char, base::FreeDeleter> ptr(
      static_cast<char*>(malloc(kAllocSize)));
  ASSERT_TRUE(ptr != NULL);
  // If two pointers are separated by less than 512MB, they are considered
  // to be in the same area.
  // Our random pointer could be anywhere within 0x3fffffffffff (46bits),
  // and we are checking that it's not withing 1GB (30 bits) from two
  // addresses (brk and mmap heap). We have roughly one chance out of
  // 2^15 to flake.
  const size_t kAreaRadius = 1<<29;
  bool in_default_mmap_heap = ArePointersToSameArea(
      ptr.get(), default_mmap_heap_address, kAreaRadius);
  EXPECT_FALSE(in_default_mmap_heap);

  bool in_default_brk_heap = ArePointersToSameArea(
      ptr.get(), brk_heap_address, kAreaRadius);
  EXPECT_FALSE(in_default_brk_heap);

  // In the implementation, we always mask our random addresses with
  // kRandomMask, so we use it as an additional detection mechanism.
  const uintptr_t kRandomMask = 0x3fffffffffffULL;
  bool impossible_random_address =
      reinterpret_cast<uintptr_t>(ptr.get()) & ~kRandomMask;
  EXPECT_FALSE(impossible_random_address);
}

#endif  // (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__x86_64__)

}  // namespace
<commit_msg>Base: account for calloc aborting in security unittests<commit_after>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <algorithm>
#include <limits>

#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_POSIX)
#include <sys/mman.h>
#include <unistd.h>
#endif

using std::nothrow;
using std::numeric_limits;

namespace {

// This function acts as a compiler optimization barrier. We use it to
// prevent the compiler from making an expression a compile-time constant.
// We also use it so that the compiler doesn't discard certain return values
// as something we don't need (see the comment with calloc below).
template <typename Type>
Type HideValueFromCompiler(volatile Type value) {
  return value;
}

// - NO_TCMALLOC (should be defined if we compile with linux_use_tcmalloc=0)
// - ADDRESS_SANITIZER because it has its own memory allocator
// - IOS does not use tcmalloc
// - OS_MACOSX does not use tcmalloc
#if !defined(NO_TCMALLOC) && !defined(ADDRESS_SANITIZER) && \
    !defined(OS_IOS) && !defined(OS_MACOSX)
  #define TCMALLOC_TEST(function) function
#else
  #define TCMALLOC_TEST(function) DISABLED_##function
#endif

// TODO(jln): switch to std::numeric_limits<int>::max() when we switch to
// C++11.
const size_t kTooBigAllocSize = INT_MAX;

// Detect runtime TCMalloc bypasses.
bool IsTcMallocBypassed() {
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
  // This should detect a TCMalloc bypass from Valgrind.
  char* g_slice = getenv("G_SLICE");
  if (g_slice && !strcmp(g_slice, "always-malloc"))
    return true;
#endif
  return false;
}

bool CallocDiesOnOOM() {
// The wrapper function in base/process_util_linux.cc that is used when we
// compile without TCMalloc will just die on OOM instead of returning NULL.
#if defined(OS_LINUX) && defined(NO_TCMALLOC)
  return true;
#else
  return false;
#endif
}

// Fake test that allow to know the state of TCMalloc by looking at bots.
TEST(SecurityTest, TCMALLOC_TEST(IsTCMallocDynamicallyBypassed)) {
  printf("Malloc is dynamically bypassed: %s\n",
         IsTcMallocBypassed() ? "yes." : "no.");
}

// The MemoryAllocationRestrictions* tests test that we can not allocate a
// memory range that cannot be indexed via an int. This is used to mitigate
// vulnerabilities in libraries that use int instead of size_t.  See
// crbug.com/169327.

TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsMalloc)) {
  if (!IsTcMallocBypassed()) {
    scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>(
        HideValueFromCompiler(malloc(kTooBigAllocSize))));
    ASSERT_TRUE(!ptr);
  }
}

TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsCalloc)) {
  if (!IsTcMallocBypassed()) {
    scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>(
        HideValueFromCompiler(calloc(kTooBigAllocSize, 1))));
    ASSERT_TRUE(!ptr);
  }
}

TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsRealloc)) {
  if (!IsTcMallocBypassed()) {
    char* orig_ptr = static_cast<char*>(malloc(1));
    ASSERT_TRUE(orig_ptr);
    scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>(
        HideValueFromCompiler(realloc(orig_ptr, kTooBigAllocSize))));
    ASSERT_TRUE(!ptr);
    // If realloc() did not succeed, we need to free orig_ptr.
    free(orig_ptr);
  }
}

typedef struct {
  char large_array[kTooBigAllocSize];
} VeryLargeStruct;

TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNew)) {
  if (!IsTcMallocBypassed()) {
    scoped_ptr<VeryLargeStruct> ptr(
        HideValueFromCompiler(new (nothrow) VeryLargeStruct));
    ASSERT_TRUE(!ptr);
  }
}

TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNewArray)) {
  if (!IsTcMallocBypassed()) {
    scoped_ptr<char[]> ptr(
        HideValueFromCompiler(new (nothrow) char[kTooBigAllocSize]));
    ASSERT_TRUE(!ptr);
  }
}

// The tests bellow check for overflows in new[] and calloc().

#if defined(OS_IOS) || defined(OS_WIN)
  #define DISABLE_ON_IOS_AND_WIN(function) DISABLED_##function
#else
  #define DISABLE_ON_IOS_AND_WIN(function) function
#endif

#if defined(ADDRESS_SANITIZER)
  #define DISABLE_ON_ASAN(function) DISABLED_##function
#else
  #define DISABLE_ON_ASAN(function) function
#endif

// There are platforms where these tests are known to fail. We would like to
// be able to easily check the status on the bots, but marking tests as
// FAILS_ is too clunky.
void OverflowTestsSoftExpectTrue(bool overflow_detected) {
  if (!overflow_detected) {
#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX)
    // Sadly, on Linux, Android, and OSX we don't have a good story yet. Don't
    // fail the test, but report.
    printf("Platform has overflow: %s\n",
           !overflow_detected ? "yes." : "no.");
#else
    // Otherwise, fail the test. (Note: EXPECT are ok in subfunctions, ASSERT
    // aren't).
    EXPECT_TRUE(overflow_detected);
#endif
  }
}

// TODO(jln): crbug.com/174947 This can't even compile on Win64.
#if !(defined(OS_WIN) && defined(ARCH_CPU_X86_64))

// Test array[TooBig][X] and array[X][TooBig] allocations for int overflows.
// IOS doesn't honor nothrow, so disable the test there.
// Disable on Windows, we suspect some are failing because of it.
TEST(SecurityTest, DISABLE_ON_IOS_AND_WIN(NewOverflow)) {
  const size_t kArraySize = 4096;
  // We want something "dynamic" here, so that the compiler doesn't
  // immediately reject crazy arrays.
  const size_t kDynamicArraySize = HideValueFromCompiler(kArraySize);
  // numeric_limits are still not constexpr until we switch to C++11, so we
  // use an ugly cast.
  const size_t kMaxSizeT = ~static_cast<size_t>(0);
  ASSERT_EQ(numeric_limits<size_t>::max(), kMaxSizeT);
  const size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
  const size_t kDynamicArraySize2 = HideValueFromCompiler(kArraySize2);
  {
    scoped_ptr<char[][kArraySize]> array_pointer(new (nothrow)
        char[kDynamicArraySize2][kArraySize]);
    OverflowTestsSoftExpectTrue(!array_pointer);
  }
  {
    scoped_ptr<char[][kArraySize2]> array_pointer(new (nothrow)
        char[kDynamicArraySize][kArraySize2]);
    OverflowTestsSoftExpectTrue(!array_pointer);
  }
}
#endif

// Call calloc(), eventually free the memory and return whether or not
// calloc() did succeed.
bool CallocReturnsNull(size_t nmemb, size_t size) {
  scoped_ptr<char, base::FreeDeleter> array_pointer(
      static_cast<char*>(calloc(nmemb, size)));
  // We need the call to HideValueFromCompiler(): we have seen LLVM
  // optimize away the call to calloc() entirely and assume
  // the pointer to not be NULL.
  return HideValueFromCompiler(array_pointer.get()) == NULL;
}

// Test if calloc() can overflow. Disable on ASAN for now since the
// overflow seems present there (crbug.com/175554).
TEST(SecurityTest, DISABLE_ON_ASAN(CallocOverflow)) {
  const size_t kArraySize = 4096;
  const size_t kMaxSizeT = numeric_limits<size_t>::max();
  const size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
  if (!CallocDiesOnOOM()) {
    EXPECT_TRUE(CallocReturnsNull(kArraySize, kArraySize2));
    EXPECT_TRUE(CallocReturnsNull(kArraySize2, kArraySize));
  } else {
    // It's also ok for calloc to just terminate the process.
#if defined(GTEST_HAS_DEATH_TEST)
    EXPECT_DEATH(CallocReturnsNull(kArraySize, kArraySize2), "");
    EXPECT_DEATH(CallocReturnsNull(kArraySize2, kArraySize), "");
#endif  // GTEST_HAS_DEATH_TEST
  }
}

#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__x86_64__)
// Useful for debugging.
void PrintProcSelfMaps() {
  int fd = open("/proc/self/maps", O_RDONLY);
  file_util::ScopedFD fd_closer(&fd);
  ASSERT_GE(fd, 0);
  char buffer[1<<13];
  int ret;
  ret = read(fd, buffer, sizeof(buffer) - 1);
  ASSERT_GT(ret, 0);
  buffer[ret - 1] = 0;
  fprintf(stdout, "%s\n", buffer);
}

// Check if ptr1 and ptr2 are separated by less than size chars.
bool ArePointersToSameArea(void* ptr1, void* ptr2, size_t size) {
  ptrdiff_t ptr_diff = reinterpret_cast<char*>(std::max(ptr1, ptr2)) -
                       reinterpret_cast<char*>(std::min(ptr1, ptr2));
  return static_cast<size_t>(ptr_diff) <= size;
}

// Check if TCMalloc uses an underlying random memory allocator.
TEST(SecurityTest, TCMALLOC_TEST(RandomMemoryAllocations)) {
  if (IsTcMallocBypassed())
    return;
  size_t kPageSize = 4096;  // We support x86_64 only.
  // Check that malloc() returns an address that is neither the kernel's
  // un-hinted mmap area, nor the current brk() area. The first malloc() may
  // not be at a random address because TCMalloc will first exhaust any memory
  // that it has allocated early on, before starting the sophisticated
  // allocators.
  void* default_mmap_heap_address =
      mmap(0, kPageSize, PROT_READ|PROT_WRITE,
           MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  ASSERT_NE(default_mmap_heap_address,
            static_cast<void*>(MAP_FAILED));
  ASSERT_EQ(munmap(default_mmap_heap_address, kPageSize), 0);
  void* brk_heap_address = sbrk(0);
  ASSERT_NE(brk_heap_address, reinterpret_cast<void*>(-1));
  ASSERT_TRUE(brk_heap_address != NULL);
  // 1 MB should get us past what TCMalloc pre-allocated before initializing
  // the sophisticated allocators.
  size_t kAllocSize = 1<<20;
  scoped_ptr<char, base::FreeDeleter> ptr(
      static_cast<char*>(malloc(kAllocSize)));
  ASSERT_TRUE(ptr != NULL);
  // If two pointers are separated by less than 512MB, they are considered
  // to be in the same area.
  // Our random pointer could be anywhere within 0x3fffffffffff (46bits),
  // and we are checking that it's not withing 1GB (30 bits) from two
  // addresses (brk and mmap heap). We have roughly one chance out of
  // 2^15 to flake.
  const size_t kAreaRadius = 1<<29;
  bool in_default_mmap_heap = ArePointersToSameArea(
      ptr.get(), default_mmap_heap_address, kAreaRadius);
  EXPECT_FALSE(in_default_mmap_heap);

  bool in_default_brk_heap = ArePointersToSameArea(
      ptr.get(), brk_heap_address, kAreaRadius);
  EXPECT_FALSE(in_default_brk_heap);

  // In the implementation, we always mask our random addresses with
  // kRandomMask, so we use it as an additional detection mechanism.
  const uintptr_t kRandomMask = 0x3fffffffffffULL;
  bool impossible_random_address =
      reinterpret_cast<uintptr_t>(ptr.get()) & ~kRandomMask;
  EXPECT_FALSE(impossible_random_address);
}

#endif  // (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__x86_64__)

}  // namespace
<|endoftext|>