<commit_before>// Copyright (c) 2015, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>

#include <gtest/gtest.h>

#include "dfs.h"

const char* so_path = "./bfs_wrapper.so";
//const char* dfs_conf = "yq01-tera60.yq01:8828";
const char* dfs_conf = "127.0.0.1:8828";

const std::string test_path("/test");

TEST(TERA_SO_TEST, TERA_SO) {
    dlerror();
    void* handle = dlopen(so_path, RTLD_LAZY | RTLD_DEEPBIND | RTLD_LOCAL);
    const char* err = dlerror();
    ASSERT_TRUE(handle != NULL);

    leveldb::DfsCreator creator = (leveldb::DfsCreator)dlsym(handle, "NewDfs");
    err = dlerror();
    ASSERT_TRUE(err == NULL);

    leveldb::Dfs* dfs = (*creator)(dfs_conf);

    /// Create dir
    ASSERT_TRUE(dfs != NULL);
    ASSERT_TRUE(0 == dfs->CreateDirectory(test_path));

    /// Open
    std::string file1 = test_path + "/file1";
    std::string file2 = test_path + "/file2";
    std::string file3 = test_path + "/file3";

    if (0 == dfs->Exists(file1)) {
        ASSERT_TRUE(0 == dfs->Delete(file1));
    }

    leveldb::DfsFile* fp = dfs->OpenFile(file1, leveldb::WRONLY);
    ASSERT_TRUE(fp != NULL);

    /// Write&Sync
    char content1[] = "File1 content";
    char content2[] = "Content for read";
    const int c1len = sizeof(content1);
    const int c2len = sizeof(content2);
    ASSERT_TRUE(c1len == fp->Write(content1, c1len));
    ASSERT_TRUE(0 == fp->Flush());
    ASSERT_TRUE(0 == fp->Sync());
    ASSERT_TRUE(c2len == fp->Write(content2, c2len));

    long lbuf[1024];
    int buflen = sizeof(lbuf);
    int bufnum = 1024;
    for (int i = 0; i < 1024; i++) {
        for (int j = 0; j < 1024; j++) {
            lbuf[j] = ((rand() << 16) | rand());
        }
        buflen = sizeof(lbuf);
        ASSERT_TRUE(buflen == fp->Write(reinterpret_cast<char*>(lbuf), buflen));
    }

    /// Close
    ASSERT_TRUE(0 == fp->CloseFile());
    delete fp;
    fp = NULL;

    /// Rename
    if (0 == dfs->Exists(file2)) {
        ASSERT_TRUE(0 == dfs->Delete(file2));
    }
    ASSERT_TRUE(0 == dfs->Rename(file1, file2));
    ASSERT_TRUE(0 == dfs->Exists(file2));
    ASSERT_TRUE(0 != dfs->Exists(file1));

    /// GetFileSize
    uint64_t fsize = 0;
    ASSERT_TRUE(0 == dfs->GetFileSize(file2, &fsize));
    ASSERT_TRUE(c1len + c2len + buflen * bufnum == static_cast<int>(fsize));

    /// Read
    fp = dfs->OpenFile(file2, leveldb::RDONLY);
    ASSERT_TRUE(fp != NULL);
    char buf[128];
    ASSERT_TRUE(c1len == fp->Read(buf, c1len));
    ASSERT_TRUE(0 == strncmp(buf, content1, c1len));
    ASSERT_TRUE(c2len == fp->Read(buf, c2len));
    printf("content2= %s, content_read= %s\n", content2, buf);
    ASSERT_TRUE(0 == strncmp(buf, content2, c2len));
    ASSERT_TRUE(c2len == fp->Pread(c1len, buf, c2len));
    ASSERT_TRUE(0 == strncmp(buf, content2, c2len));
    ASSERT_TRUE(0 == fp->CloseFile());
    delete fp;
    fp = NULL;

    /// Sync
    dfs->Delete(file3);
    fp = dfs->OpenFile(file3, leveldb::WRONLY);
    ASSERT_TRUE(fp != NULL);
    ASSERT_TRUE(c1len == fp->Write(content1, c1len));
    ASSERT_TRUE(0 == fp->Flush());
    ASSERT_TRUE(0 == fp->Sync());
    uint64_t file_size = 0;
    ASSERT_TRUE(0 == dfs->GetFileSize(file3, &file_size));
    ASSERT_TRUE(file_size == (uint64_t)c1len);
    ASSERT_TRUE(c2len == fp->Write(content2, c2len));

    leveldb::DfsFile* nfp = dfs->OpenFile(file3, leveldb::RDONLY);
    ASSERT_TRUE(nfp != NULL);
    ASSERT_TRUE(c1len == nfp->Read(buf, c1len));
    ASSERT_TRUE(0 == strncmp(buf, content1, c1len));
    nfp->Read(buf, c2len);  // Undefined
    ASSERT_TRUE(0 == nfp->Read(buf, c2len));
    ASSERT_TRUE(0 == nfp->CloseFile());

    /// List directory
    std::vector<std::string> result;
    ASSERT_TRUE(0 == dfs->ListDirectory(test_path, &result));
    ASSERT_TRUE(2 == result.size());
    ASSERT_TRUE(file2.substr(file2.rfind('/')+1) == result[0]);

    /// Delete
    ASSERT_TRUE(0 == dfs->Delete(file2));
    ASSERT_TRUE(0 != dfs->Exists(file2));

    /// Delete directory
    result.clear();
    ASSERT_TRUE(0 == dfs->DeleteDirectory(test_path));
    ASSERT_TRUE(0 != dfs->ListDirectory(test_path, &result));
}

int main(int argc, char* argv[]) {
    testing::InitGoogleTest(&argc, argv);
    if (argc > 1) {
        dfs_conf = argv[1];
    }
    return RUN_ALL_TESTS();
}

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<commit_msg>Fix bfs_test<commit_after>// Copyright (c) 2015, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>

#include <gtest/gtest.h>

#include "dfs.h"

const char* so_path = "./bfs_wrapper.so";
//const char* dfs_conf = "yq01-tera60.yq01:8828";
const char* dfs_conf = "127.0.0.1:8827,127.0.0.1:8828,127.0.0.1:8829";

const std::string test_path("/test");

TEST(TERA_SO_TEST, TERA_SO) {
    dlerror();
    void* handle = dlopen(so_path, RTLD_LAZY | RTLD_DEEPBIND | RTLD_LOCAL);
    const char* err = dlerror();
    ASSERT_TRUE(handle != NULL);

    leveldb::DfsCreator creator = (leveldb::DfsCreator)dlsym(handle, "NewDfs");
    err = dlerror();
    ASSERT_TRUE(err == NULL);

    leveldb::Dfs* dfs = (*creator)(dfs_conf);

    /// Create dir
    ASSERT_TRUE(dfs != NULL);
    ASSERT_TRUE(0 == dfs->CreateDirectory(test_path));

    /// Open
    std::string file1 = test_path + "/file1";
    std::string file2 = test_path + "/file2";
    std::string file3 = test_path + "/file3";

    if (0 == dfs->Exists(file1)) {
        ASSERT_TRUE(0 == dfs->Delete(file1));
    }

    leveldb::DfsFile* fp = dfs->OpenFile(file1, leveldb::WRONLY);
    ASSERT_TRUE(fp != NULL);

    /// Write&Sync
    char content1[] = "File1 content";
    char content2[] = "Content for read";
    const int c1len = sizeof(content1);
    const int c2len = sizeof(content2);
    ASSERT_TRUE(c1len == fp->Write(content1, c1len));
    ASSERT_TRUE(0 == fp->Flush());
    ASSERT_TRUE(0 == fp->Sync());
    ASSERT_TRUE(c2len == fp->Write(content2, c2len));

    long lbuf[1024];
    int buflen = sizeof(lbuf);
    int bufnum = 1024;
    for (int i = 0; i < 1024; i++) {
        for (int j = 0; j < 1024; j++) {
            lbuf[j] = ((rand() << 16) | rand());
        }
        buflen = sizeof(lbuf);
        ASSERT_TRUE(buflen == fp->Write(reinterpret_cast<char*>(lbuf), buflen));
    }

    /// Close
    ASSERT_TRUE(0 == fp->CloseFile());
    delete fp;
    fp = NULL;

    /// Rename
    if (0 == dfs->Exists(file2)) {
        ASSERT_TRUE(0 == dfs->Delete(file2));
    }
    ASSERT_TRUE(0 == dfs->Rename(file1, file2));
    ASSERT_TRUE(0 == dfs->Exists(file2));
    ASSERT_TRUE(0 != dfs->Exists(file1));

    /// GetFileSize
    uint64_t fsize = 0;
    ASSERT_TRUE(0 == dfs->GetFileSize(file2, &fsize));
    ASSERT_TRUE(c1len + c2len + buflen * bufnum == static_cast<int>(fsize));

    /// Read
    fp = dfs->OpenFile(file2, leveldb::RDONLY);
    ASSERT_TRUE(fp != NULL);
    char buf[128];
    ASSERT_TRUE(c1len == fp->Read(buf, c1len));
    ASSERT_TRUE(0 == strncmp(buf, content1, c1len));
    ASSERT_TRUE(c2len == fp->Read(buf, c2len));
    printf("content2= %s, content_read= %s\n", content2, buf);
    ASSERT_TRUE(0 == strncmp(buf, content2, c2len));
    ASSERT_TRUE(c2len == fp->Pread(c1len, buf, c2len));
    ASSERT_TRUE(0 == strncmp(buf, content2, c2len));
    ASSERT_TRUE(0 == fp->CloseFile());
    delete fp;
    fp = NULL;

    /// Sync
    dfs->Delete(file3);
    fp = dfs->OpenFile(file3, leveldb::WRONLY);
    ASSERT_TRUE(fp != NULL);
    ASSERT_TRUE(c1len == fp->Write(content1, c1len));
    ASSERT_TRUE(0 == fp->Flush());
    ASSERT_TRUE(0 == fp->Sync());
    uint64_t file_size = 0;
    ASSERT_TRUE(0 == dfs->GetFileSize(file3, &file_size));
    ASSERT_TRUE(file_size == (uint64_t)c1len);
    ASSERT_TRUE(c2len == fp->Write(content2, c2len));

    leveldb::DfsFile* nfp = dfs->OpenFile(file3, leveldb::RDONLY);
    ASSERT_TRUE(nfp != NULL);
    ASSERT_TRUE(c1len == nfp->Read(buf, c1len));
    ASSERT_TRUE(0 == strncmp(buf, content1, c1len));
    nfp->Read(buf, c2len);  // Undefined
    ASSERT_TRUE(0 == nfp->Read(buf, c2len));
    ASSERT_TRUE(0 == nfp->CloseFile());

    /// List directory
    std::vector<std::string> result;
    ASSERT_TRUE(0 == dfs->ListDirectory(test_path, &result));
    ASSERT_TRUE(2 == result.size());
    ASSERT_TRUE(file2.substr(file2.rfind('/')+1) == result[0]);

    /// Delete
    ASSERT_TRUE(0 == dfs->Delete(file2));
    ASSERT_TRUE(0 != dfs->Exists(file2));

    /// Delete directory
    result.clear();
    ASSERT_TRUE(0 == dfs->DeleteDirectory(test_path));
    ASSERT_TRUE(0 != dfs->ListDirectory(test_path, &result));
}

int main(int argc, char* argv[]) {
    testing::InitGoogleTest(&argc, argv);
    if (argc > 1) {
        dfs_conf = argv[1];
    }
    return RUN_ALL_TESTS();
}

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include <climits>

#include "AclManager.h"
#include "NebulaLog.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const char * AclManager::table = "acl";

const char * AclManager::db_names = "oid, user, resource, rights";

const char * AclManager::db_bootstrap = "CREATE TABLE IF NOT EXISTS "
    "acl (oid INT PRIMARY KEY, user BIGINT, resource BIGINT, rights BIGINT)";

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::init_cb(void *nil, int num, char **values, char **names)
{
    lastOID = -1;

    if ( values[0] != 0 )
    {
        lastOID = atoi(values[0]);
    }

    return 0;
}

/* -------------------------------------------------------------------------- */

AclManager::AclManager(SqlDB * _db) :
    db(_db), lastOID(-1)
{
    ostringstream oss;

    // TODO:
    // pthread_mutex_init(&mutex, 0);

    set_callback(static_cast<Callbackable::Callback> (&AclManager::init_cb));

    oss << "SELECT last_oid FROM pool_control WHERE tablename='" << table
            << "'";

    db->exec(oss, this);

    unset_callback();
}
;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::start()
{
    return select();
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

AclManager::~AclManager()
{
    multimap<long long, AclRule *>::iterator  it;

    for ( it = acl_rules.begin(); it != acl_rules.end(); it++ )
    {
        delete it->second;
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const bool AclManager::authorize(int uid, const set<int> &user_groups,
        AuthRequest::Object obj_type, int obj_id, int obj_gid,
        AuthRequest::Operation op)
{
    ostringstream oss;

    multimap<long long, AclRule *>::iterator        it;
    pair<multimap<long long, AclRule *>::iterator,
         multimap<long long, AclRule *>::iterator>  index;

    bool auth = false;

    // Build masks for request
    long long user_req;
    long long resource_oid_req  = obj_type + AclRule::INDIVIDUAL_ID + obj_id;
    long long resource_gid_req  = obj_type + AclRule::GROUP_ID + obj_gid;
    long long resource_all_req  = obj_type + AclRule::ALL_ID;
    long long rights_req        = op;

    long long individual_obj_type =
            ( obj_type | AclRule::INDIVIDUAL_ID | 0xFFFFFFFF );

    long long group_obj_type =
            ( obj_type | AclRule::GROUP_ID | 0xFFFFFFFF );

    AclRule request_rule(-1, AclRule::INDIVIDUAL_ID + uid, resource_oid_req,
                        rights_req);
    oss << "Request " << request_rule.to_str();
    NebulaLog::log("ACL",Log::DEBUG,oss);

    // Look for rules that apply to everyone

    user_req = AclRule::ALL_ID;
    auth = match_rules(user_req, resource_oid_req, resource_gid_req,
            resource_all_req, rights_req, individual_obj_type, group_obj_type);

    if ( auth == true )
    {
        return true;
    }

    // Look for rules that apply to the individual user id
    user_req = AclRule::INDIVIDUAL_ID + uid;

    auth = match_rules(user_req, resource_oid_req, resource_gid_req,
            resource_all_req, rights_req, individual_obj_type, group_obj_type);

    if ( auth == true )
    {
        return true;
    }

    // Look for rules that apply to each one of the user's groups

    set<int>::iterator  g_it;

    for (g_it = user_groups.begin(); g_it != user_groups.end(); g_it++)
    {
        user_req = AclRule::GROUP_ID + *g_it;

        auth = match_rules(user_req, resource_oid_req, resource_gid_req,
                resource_all_req, rights_req, individual_obj_type,
                group_obj_type);

        if ( auth == true )
        {
            return true;
        }
    }

    oss.str("No more rules, permission not granted ");
    NebulaLog::log("ACL",Log::DEBUG,oss);

    return false;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

bool AclManager::match_rules(
        long long user_req,
        long long resource_oid_req,
        long long resource_gid_req,
        long long resource_all_req,
        long long rights_req,
        long long individual_obj_type,
        long long group_obj_type)

{
    bool auth;
    ostringstream oss;

    multimap<long long, AclRule *>::iterator        it;

    pair<multimap<long long, AclRule *>::iterator,
         multimap<long long, AclRule *>::iterator>  index;

    index = acl_rules.equal_range( user_req );

    for ( it = index.first; it != index.second; it++)
    {
        oss.str("");
        oss << "> Rule  " << it->second->to_str();
        NebulaLog::log("ACL",Log::DEBUG,oss);

        auth =
          // Rule grants the requested rights
          ( ( it->second->rights & rights_req ) == rights_req )
          &&
          (
            // Rule grants permission for all objects of this type
            ( it->second->resource == resource_all_req )
            ||
            // Or rule's object type and group object ID match
            ( ( it->second->resource & group_obj_type ) == resource_gid_req )
            ||
            // Or rule's object type and individual object ID match
            ( ( it->second->resource & individual_obj_type ) == resource_oid_req )
          );

        if ( auth == true )
        {
            oss.str("Permission granted");
            NebulaLog::log("ACL",Log::DEBUG,oss);

            return true;
        }
    }

    return false;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::add_rule(long long user, long long resource, long long rights,
                        string& error_str)
{
    if (lastOID == INT_MAX)
    {
        lastOID = -1;
    }

    AclRule * rule = new AclRule(++lastOID, user, resource, rights);

    ostringstream   oss;
    int             rc;

    multimap<long long, AclRule *>::iterator        it;
    pair<multimap<long long, AclRule *>::iterator,
         multimap<long long, AclRule *>::iterator>  index;

    bool found = false;

    index = acl_rules.equal_range( user );

    for ( it = index.first; (it != index.second && !found); it++)
    {
        found = *(it->second) == *rule;
        if ( it->second->resource == resource &&
             it->second->rights == rights )
        {
            found = true;
        }
    }

    if ( found )
    {
        goto error_duplicated;
    }

    if ( rule->malformed(error_str) )
    {
        goto error_malformed;
    }

    rc = insert(rule);

    if ( rc != 0 )
    {
        goto error_insert;
    }

    acl_rules.insert( make_pair(rule->user, rule) );
    acl_rules_oids.insert( make_pair(rule->oid, rule) );

    update_lastOID();

    return lastOID;

error_duplicated:
    oss << "Rule " << rule->to_str() << " already exists";
    rc = -1;

    goto error_common;

error_malformed:
    oss << "Rule " << rule->to_str() << " is malformed: " << error_str;
    rc = -2;

    goto error_common;

error_insert:
    oss << "Error inserting rule in DB";
    rc = -3;

    goto error_common;

error_common:
    error_str = oss.str();

    delete rule;
    lastOID--;

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::del_rule(int oid, string& error_str)
{

    multimap<long long, AclRule *>::iterator        it;
    pair<multimap<long long, AclRule *>::iterator,
         multimap<long long, AclRule *>::iterator>  index;

    AclRule *   rule;
    int         rc;
    bool        found = false;

    // Check the rule exists
    found = acl_rules_oids.count(oid) > 0;

    if ( !found )
    {
        ostringstream oss;
        oss << "Rule " << oid << " does not exist";
        error_str = oss.str();

        return -1;
    }

    rule = acl_rules_oids[oid];

    // Look for it in the multimap

    found = false;

    index = acl_rules.equal_range( rule->user );

    it = index.first;
    while ( !found && it != index.second )
    {
        found = *rule == *(it->second);

        if ( !found )
        {
            it++;
        }
    }

    if ( !found )
    {
        ostringstream oss;
        oss << "Internal error: ACL Rule " << oid
            << " indexed by oid, but not in by user attribute";

        NebulaLog::log("ACL",Log::ERROR,oss);

        return -1;
    }

    rc = drop( oid );

    if ( rc != 0 )
    {
        error_str = "SQL DB error";
        return -1;
    }

    delete it->second;

    acl_rules.erase( it );
    acl_rules_oids.erase( oid );

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AclManager::update_lastOID()
{
    // db->escape_str is not used for 'table' since its name can't be set in
    // any way by the user, it is hardcoded.

    ostringstream oss;

    oss << "REPLACE INTO pool_control (tablename, last_oid) VALUES ("
        << "'" <<   table       << "',"
        <<          lastOID     << ")";

    db->exec(oss);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::select_cb(void *nil, int num, char **values, char **names)
{
    if ( (num != 4)   ||
         (!values[0]) ||
         (!values[1]) ||
         (!values[2]) ||
         (!values[3]) )
    {
        return -1;
    }

    ostringstream oss;
    istringstream iss;

    int oid = atoi(values[0]);

    long long rule_values[3];

    for ( int i = 0; i < 3; i++ )
    {
        iss.str( values[i+1] );

        iss >> rule_values[i];

        if ( iss.fail() == true )
        {
            return -1;
        }

        iss.clear();
    }

    // TODO: Use add_rule() instead, to check possible errors, or assume
    // that anything that was stored into the DB is trustworthy?
    AclRule * rule = new AclRule(oid, rule_values[0], rule_values[1],
                                rule_values[2]);

    oss << "Loading ACL Rule " << rule->to_str();
    NebulaLog::log("ACL",Log::DDEBUG,oss);

    acl_rules.insert( make_pair(rule->user, rule) );
    acl_rules_oids.insert( make_pair(rule->oid, rule) );

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::select()
{
    ostringstream   oss;
    int             rc;

    oss << "SELECT " << db_names << " FROM " << table;

    set_callback(static_cast<Callbackable::Callback>(&AclManager::select_cb));

    rc = db->exec(oss,this);

    unset_callback();

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::insert(AclRule * rule)
{
    ostringstream   oss;
    int             rc;

    // Construct the SQL statement to Insert

    oss <<  "INSERT INTO "  << table <<" ("<< db_names <<") VALUES ("
        <<  rule->oid       << ","
        <<  rule->user      << ","
        <<  rule->resource  << ","
        <<  rule->rights    << ")";

    rc = db->exec(oss);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::drop(int oid)
{
    ostringstream   oss;
    int             rc;

    oss << "DELETE FROM " << table << " WHERE "
        << "oid=" << oid;

    rc = db->exec(oss);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::dump(ostringstream& oss)
{
    map<int, AclRule *>::iterator        it;
    string xml;

    oss << "<ACL_POOL>";

    for ( it = acl_rules_oids.begin() ; it != acl_rules_oids.end(); it++ )
    {
        oss << it->second->to_xml(xml);
    }

    oss << "</ACL_POOL>";

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
<commit_msg>Feature #687: Remove duplicated search test in AclManager::add_rule<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include <climits>

#include "AclManager.h"
#include "NebulaLog.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const char * AclManager::table = "acl";

const char * AclManager::db_names = "oid, user, resource, rights";

const char * AclManager::db_bootstrap = "CREATE TABLE IF NOT EXISTS "
    "acl (oid INT PRIMARY KEY, user BIGINT, resource BIGINT, rights BIGINT)";

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::init_cb(void *nil, int num, char **values, char **names)
{
    lastOID = -1;

    if ( values[0] != 0 )
    {
        lastOID = atoi(values[0]);
    }

    return 0;
}

/* -------------------------------------------------------------------------- */

AclManager::AclManager(SqlDB * _db) :
    db(_db), lastOID(-1)
{
    ostringstream oss;

    // TODO:
    // pthread_mutex_init(&mutex, 0);

    set_callback(static_cast<Callbackable::Callback> (&AclManager::init_cb));

    oss << "SELECT last_oid FROM pool_control WHERE tablename='" << table
            << "'";

    db->exec(oss, this);

    unset_callback();
}
;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::start()
{
    return select();
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

AclManager::~AclManager()
{
    multimap<long long, AclRule *>::iterator  it;

    for ( it = acl_rules.begin(); it != acl_rules.end(); it++ )
    {
        delete it->second;
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const bool AclManager::authorize(int uid, const set<int> &user_groups,
        AuthRequest::Object obj_type, int obj_id, int obj_gid,
        AuthRequest::Operation op)
{
    ostringstream oss;

    multimap<long long, AclRule *>::iterator        it;
    pair<multimap<long long, AclRule *>::iterator,
         multimap<long long, AclRule *>::iterator>  index;

    bool auth = false;

    // Build masks for request
    long long user_req;
    long long resource_oid_req  = obj_type + AclRule::INDIVIDUAL_ID + obj_id;
    long long resource_gid_req  = obj_type + AclRule::GROUP_ID + obj_gid;
    long long resource_all_req  = obj_type + AclRule::ALL_ID;
    long long rights_req        = op;

    long long individual_obj_type =
            ( obj_type | AclRule::INDIVIDUAL_ID | 0xFFFFFFFF );

    long long group_obj_type =
            ( obj_type | AclRule::GROUP_ID | 0xFFFFFFFF );

    AclRule request_rule(-1, AclRule::INDIVIDUAL_ID + uid, resource_oid_req,
                        rights_req);
    oss << "Request " << request_rule.to_str();
    NebulaLog::log("ACL",Log::DEBUG,oss);

    // Look for rules that apply to everyone

    user_req = AclRule::ALL_ID;
    auth = match_rules(user_req, resource_oid_req, resource_gid_req,
            resource_all_req, rights_req, individual_obj_type, group_obj_type);

    if ( auth == true )
    {
        return true;
    }

    // Look for rules that apply to the individual user id
    user_req = AclRule::INDIVIDUAL_ID + uid;

    auth = match_rules(user_req, resource_oid_req, resource_gid_req,
            resource_all_req, rights_req, individual_obj_type, group_obj_type);

    if ( auth == true )
    {
        return true;
    }

    // Look for rules that apply to each one of the user's groups

    set<int>::iterator  g_it;

    for (g_it = user_groups.begin(); g_it != user_groups.end(); g_it++)
    {
        user_req = AclRule::GROUP_ID + *g_it;

        auth = match_rules(user_req, resource_oid_req, resource_gid_req,
                resource_all_req, rights_req, individual_obj_type,
                group_obj_type);

        if ( auth == true )
        {
            return true;
        }
    }

    oss.str("No more rules, permission not granted ");
    NebulaLog::log("ACL",Log::DEBUG,oss);

    return false;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

bool AclManager::match_rules(
        long long user_req,
        long long resource_oid_req,
        long long resource_gid_req,
        long long resource_all_req,
        long long rights_req,
        long long individual_obj_type,
        long long group_obj_type)

{
    bool auth;
    ostringstream oss;

    multimap<long long, AclRule *>::iterator        it;

    pair<multimap<long long, AclRule *>::iterator,
         multimap<long long, AclRule *>::iterator>  index;

    index = acl_rules.equal_range( user_req );

    for ( it = index.first; it != index.second; it++)
    {
        oss.str("");
        oss << "> Rule  " << it->second->to_str();
        NebulaLog::log("ACL",Log::DEBUG,oss);

        auth =
          // Rule grants the requested rights
          ( ( it->second->rights & rights_req ) == rights_req )
          &&
          (
            // Rule grants permission for all objects of this type
            ( it->second->resource == resource_all_req )
            ||
            // Or rule's object type and group object ID match
            ( ( it->second->resource & group_obj_type ) == resource_gid_req )
            ||
            // Or rule's object type and individual object ID match
            ( ( it->second->resource & individual_obj_type ) == resource_oid_req )
          );

        if ( auth == true )
        {
            oss.str("Permission granted");
            NebulaLog::log("ACL",Log::DEBUG,oss);

            return true;
        }
    }

    return false;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::add_rule(long long user, long long resource, long long rights,
                        string& error_str)
{
    if (lastOID == INT_MAX)
    {
        lastOID = -1;
    }

    AclRule * rule = new AclRule(++lastOID, user, resource, rights);

    ostringstream   oss;
    int             rc;

    multimap<long long, AclRule *>::iterator        it;
    pair<multimap<long long, AclRule *>::iterator,
         multimap<long long, AclRule *>::iterator>  index;

    bool found = false;

    index = acl_rules.equal_range( user );

    for ( it = index.first; (it != index.second && !found); it++)
    {
        found = *(it->second) == *rule;
    }

    if ( found )
    {
        goto error_duplicated;
    }

    if ( rule->malformed(error_str) )
    {
        goto error_malformed;
    }

    rc = insert(rule);

    if ( rc != 0 )
    {
        goto error_insert;
    }

    acl_rules.insert( make_pair(rule->user, rule) );
    acl_rules_oids.insert( make_pair(rule->oid, rule) );

    update_lastOID();

    return lastOID;

error_duplicated:
    oss << "Rule " << rule->to_str() << " already exists";
    rc = -1;

    goto error_common;

error_malformed:
    oss << "Rule " << rule->to_str() << " is malformed: " << error_str;
    rc = -2;

    goto error_common;

error_insert:
    oss << "Error inserting rule in DB";
    rc = -3;

    goto error_common;

error_common:
    error_str = oss.str();

    delete rule;
    lastOID--;

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::del_rule(int oid, string& error_str)
{

    multimap<long long, AclRule *>::iterator        it;
    pair<multimap<long long, AclRule *>::iterator,
         multimap<long long, AclRule *>::iterator>  index;

    AclRule *   rule;
    int         rc;
    bool        found = false;

    // Check the rule exists
    found = acl_rules_oids.count(oid) > 0;

    if ( !found )
    {
        ostringstream oss;
        oss << "Rule " << oid << " does not exist";
        error_str = oss.str();

        return -1;
    }

    rule = acl_rules_oids[oid];

    // Look for it in the multimap

    found = false;

    index = acl_rules.equal_range( rule->user );

    it = index.first;
    while ( !found && it != index.second )
    {
        found = *rule == *(it->second);

        if ( !found )
        {
            it++;
        }
    }

    if ( !found )
    {
        ostringstream oss;
        oss << "Internal error: ACL Rule " << oid
            << " indexed by oid, but not in by user attribute";

        NebulaLog::log("ACL",Log::ERROR,oss);

        return -1;
    }

    rc = drop( oid );

    if ( rc != 0 )
    {
        error_str = "SQL DB error";
        return -1;
    }

    delete it->second;

    acl_rules.erase( it );
    acl_rules_oids.erase( oid );

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void AclManager::update_lastOID()
{
    // db->escape_str is not used for 'table' since its name can't be set in
    // any way by the user, it is hardcoded.

    ostringstream oss;

    oss << "REPLACE INTO pool_control (tablename, last_oid) VALUES ("
        << "'" <<   table       << "',"
        <<          lastOID     << ")";

    db->exec(oss);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::select_cb(void *nil, int num, char **values, char **names)
{
    if ( (num != 4)   ||
         (!values[0]) ||
         (!values[1]) ||
         (!values[2]) ||
         (!values[3]) )
    {
        return -1;
    }

    ostringstream oss;
    istringstream iss;

    int oid = atoi(values[0]);

    long long rule_values[3];

    for ( int i = 0; i < 3; i++ )
    {
        iss.str( values[i+1] );

        iss >> rule_values[i];

        if ( iss.fail() == true )
        {
            return -1;
        }

        iss.clear();
    }

    // TODO: Use add_rule() instead, to check possible errors, or assume
    // that anything that was stored into the DB is trustworthy?
    AclRule * rule = new AclRule(oid, rule_values[0], rule_values[1],
                                rule_values[2]);

    oss << "Loading ACL Rule " << rule->to_str();
    NebulaLog::log("ACL",Log::DDEBUG,oss);

    acl_rules.insert( make_pair(rule->user, rule) );
    acl_rules_oids.insert( make_pair(rule->oid, rule) );

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::select()
{
    ostringstream   oss;
    int             rc;

    oss << "SELECT " << db_names << " FROM " << table;

    set_callback(static_cast<Callbackable::Callback>(&AclManager::select_cb));

    rc = db->exec(oss,this);

    unset_callback();

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::insert(AclRule * rule)
{
    ostringstream   oss;
    int             rc;

    // Construct the SQL statement to Insert

    oss <<  "INSERT INTO "  << table <<" ("<< db_names <<") VALUES ("
        <<  rule->oid       << ","
        <<  rule->user      << ","
        <<  rule->resource  << ","
        <<  rule->rights    << ")";

    rc = db->exec(oss);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::drop(int oid)
{
    ostringstream   oss;
    int             rc;

    oss << "DELETE FROM " << table << " WHERE "
        << "oid=" << oid;

    rc = db->exec(oss);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int AclManager::dump(ostringstream& oss)
{
    map<int, AclRule *>::iterator        it;
    string xml;

    oss << "<ACL_POOL>";

    for ( it = acl_rules_oids.begin() ; it != acl_rules_oids.end(); it++ )
    {
        oss << it->second->to_xml(xml);
    }

    oss << "</ACL_POOL>";

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright 2016 ScyllaDB
 */

#pragma once

#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <iosfwd>
#include <boost/container/static_vector.hpp>

#include "core/sstring.hh"

namespace seastar {

struct shared_object {
    sstring name;
    uintptr_t begin;
    uintptr_t end; // C++-style, last addr + 1
};

struct frame {
    const shared_object* so;
    uintptr_t addr;
};

bool operator==(const frame& a, const frame& b);

// If addr doesn't seem to belong to any of the provided shared objects, it
// will be considered as part of the executable.
frame decorate(uintptr_t addr);

// Invokes func for each frame passing it as argument.
template<typename Func>
void backtrace(Func&& func) noexcept(noexcept(func(frame()))) {
    unw_context_t context;
    if (unw_getcontext(&context) < 0) {
        return;
    }

    unw_cursor_t cursor;
    if (unw_init_local(&cursor, &context) < 0) {
        return;
    }

    while (unw_step(&cursor) > 0) {
        unw_word_t ip;
        if (unw_get_reg(&cursor, UNW_REG_IP, &ip) < 0) {
            break;
        }
        if (!ip) {
            break;
        }
        func(decorate(ip - 1));
    }
}

class saved_backtrace {
public:
    using vector_type = boost::container::static_vector<frame, 64>;
private:
    vector_type _frames;
public:
    saved_backtrace() = default;
    saved_backtrace(vector_type f) : _frames(std::move(f)) {}
    size_t hash() const;

    friend std::ostream& operator<<(std::ostream& out, const saved_backtrace&);

    bool operator==(const saved_backtrace& o) const {
        return _frames == o._frames;
    }

    bool operator!=(const saved_backtrace& o) const {
        return !(*this == o);
    }
};

}

namespace std {

template<>
struct hash<seastar::saved_backtrace> {
    size_t operator()(const seastar::saved_backtrace& b) const {
        return b.hash();
    }
};

}

namespace seastar {

saved_backtrace current_backtrace() noexcept;
std::ostream& operator<<(std::ostream& out, const saved_backtrace& b);

}
<commit_msg>util: Add throw_with_backtrace helper to add backtraces to exceptions.<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright 2016 ScyllaDB
 */

#pragma once

#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <iosfwd>
#include <boost/container/static_vector.hpp>

#include "core/sstring.hh"
#include "core/print.hh"

namespace seastar {

struct shared_object {
    sstring name;
    uintptr_t begin;
    uintptr_t end; // C++-style, last addr + 1
};

struct frame {
    const shared_object* so;
    uintptr_t addr;
};

bool operator==(const frame& a, const frame& b);

// If addr doesn't seem to belong to any of the provided shared objects, it
// will be considered as part of the executable.
frame decorate(uintptr_t addr);

// Invokes func for each frame passing it as argument.
template<typename Func>
void backtrace(Func&& func) noexcept(noexcept(func(frame()))) {
    unw_context_t context;
    if (unw_getcontext(&context) < 0) {
        return;
    }

    unw_cursor_t cursor;
    if (unw_init_local(&cursor, &context) < 0) {
        return;
    }

    while (unw_step(&cursor) > 0) {
        unw_word_t ip;
        if (unw_get_reg(&cursor, UNW_REG_IP, &ip) < 0) {
            break;
        }
        if (!ip) {
            break;
        }
        func(decorate(ip - 1));
    }
}

class saved_backtrace {
public:
    using vector_type = boost::container::static_vector<frame, 64>;
private:
    vector_type _frames;
public:
    saved_backtrace() = default;
    saved_backtrace(vector_type f) : _frames(std::move(f)) {}
    size_t hash() const;

    friend std::ostream& operator<<(std::ostream& out, const saved_backtrace&);

    bool operator==(const saved_backtrace& o) const {
        return _frames == o._frames;
    }

    bool operator!=(const saved_backtrace& o) const {
        return !(*this == o);
    }
};

}

namespace std {

template<>
struct hash<seastar::saved_backtrace> {
    size_t operator()(const seastar::saved_backtrace& b) const {
        return b.hash();
    }
};

}

namespace seastar {

saved_backtrace current_backtrace() noexcept;
std::ostream& operator<<(std::ostream& out, const saved_backtrace& b);

namespace internal {

template<class Exc>
class backtraced : public Exc {
    std::shared_ptr<sstring> _backtrace;
public:
    template<typename... Args>
    backtraced(Args&&... args)
            : Exc(std::forward<Args>(args)...)
            , _backtrace(std::make_shared<sstring>(sprint("%s Backtrace: %s", Exc::what(), current_backtrace()))) {}

    /**
     * Returns the original exception message with a backtrace appended to it
     *
     * @return original exception message followed by a backtrace
     */
    virtual const char* what() const noexcept override {
        assert(_backtrace);
        return _backtrace->c_str();
    }
};

}

    /**
     * Throws an exception of unspecified type that is derived from the Exc type
     * with a backtrace attached to its message
     *
     * @tparam Exc exception type to be caught at the receiving side
     * @tparam Args types of arguments forwarded to the constructor of Exc
     * @param args arguments forwarded to the constructor of Exc
     * @return never returns (throws an exception)
     */
template <class Exc, typename... Args>
[[noreturn]]
void
throw_with_backtrace(Args&&... args) {
    using exc_type = std::decay_t<Exc>;
    static_assert(std::is_base_of<std::exception, exc_type>::value,
            "throw_with_backtrace only works with exception types");
    throw internal::backtraced<exc_type>(std::forward<Args>(args)...);
};

}
<|endoftext|>


<commit_before>/**
 *  @file
 *  @copyright defined in eosio/LICENSE.txt
 */
#include <appbase/application.hpp>

#include <eosio/chain_plugin/chain_plugin.hpp>
#include <eosio/http_plugin/http_plugin.hpp>
#include <eosio/net_plugin/net_plugin.hpp>
#include <eosio/producer_plugin/producer_plugin.hpp>

#include <fc/log/logger_config.hpp>
#include <fc/log/appender.hpp>
#include <fc/exception/exception.hpp>

#include <boost/dll/runtime_symbol_info.hpp>
#include <boost/exception/diagnostic_information.hpp>

#include "config.hpp"

using namespace appbase;
using namespace eosio;

namespace fc {
   std::unordered_map<std::string,appender::ptr>& get_appender_map();
}

namespace detail {

void configure_logging(const bfs::path& config_path)
{
   try {
      try {
         fc::configure_logging(config_path);
      } catch (...) {
         elog("Error reloading logging.json");
         throw;
      }
   } catch (const fc::exception& e) {
      elog("${e}", ("e",e.to_detail_string()));
   } catch (const boost::exception& e) {
      elog("${e}", ("e",boost::diagnostic_information(e)));
   } catch (const std::exception& e) {
      elog("${e}", ("e",e.what()));
   } catch (...) {
      // empty
   }
}

} // namespace detail

void logging_conf_handler()
{
   ilog("Received HUP.  Reloading logging configuration.");
   auto config_path = app().get_logging_conf();
   if(fc::exists(config_path))
      ::detail::configure_logging(config_path);
   for(auto iter : fc::get_appender_map())
      iter.second->initialize(app().get_io_service());
}

void initialize_logging()
{
   auto config_path = app().get_logging_conf();
   if(fc::exists(config_path))
     fc::configure_logging(config_path); // intentionally allowing exceptions to escape
   for(auto iter : fc::get_appender_map())
     iter.second->initialize(app().get_io_service());

   app().set_sighup_callback(logging_conf_handler);
}

enum return_codes {
   OTHER_FAIL        = -2,
   INITIALIZE_FAIL   = -1,
   SUCCESS           = 0,
   BAD_ALLOC         = 1,
   DATABASE_DIRTY    = 2,
   FIXED_REVERSIBLE  = 3,
   EXTRACTED_GENESIS = 4,
   NODE_MANAGEMENT_SUCCESS = 5
};

int main(int argc, char** argv)
{
   try {
      fc::set_os_thread_name( "main" );
      app().set_version(eosio::nodeos::config::version);

      auto root = fc::app_path();
      app().set_default_data_dir(root / "eosio/nodeos/data" );
      app().set_default_config_dir(root / "eosio/nodeos/config" );
      http_plugin::set_defaults({
         .default_unix_socket_path = "",
         .default_http_port = 8888
      });
      if(!app().initialize<chain_plugin, net_plugin, producer_plugin>(argc, argv))
         return INITIALIZE_FAIL;
      initialize_logging();
      ilog("nodeos version ${ver}", ("ver", app().version_string()));
      ilog("eosio root is ${root}", ("root", root.string()));
      ilog("nodeos using configuration file ${c}", ("c", app().full_config_file_path().string()));
      ilog("nodeos data directory is ${d}", ("d", app().data_dir().string()));
      app().startup();
      app().exec();
   } catch( const extract_genesis_state_exception& e ) {
      return EXTRACTED_GENESIS;
   } catch( const fixed_reversible_db_exception& e ) {
      return FIXED_REVERSIBLE;
   } catch( const node_management_success& e ) {
      return NODE_MANAGEMENT_SUCCESS;
   } catch( const fc::exception& e ) {
      if( e.code() == fc::std_exception_code ) {
         if( e.top_message().find( "database dirty flag set" ) != std::string::npos ) {
            elog( "database dirty flag set (likely due to unclean shutdown): replay required" );
            return DATABASE_DIRTY;
         } else if( e.top_message().find( "database metadata dirty flag set" ) != std::string::npos ) {
            elog( "database metadata dirty flag set (likely due to unclean shutdown): replay required" );
            return DATABASE_DIRTY;
         }
      }
      elog( "${e}", ("e", e.to_detail_string()));
      return OTHER_FAIL;
   } catch( const boost::interprocess::bad_alloc& e ) {
      elog("bad alloc");
      return BAD_ALLOC;
   } catch( const boost::exception& e ) {
      elog("${e}", ("e",boost::diagnostic_information(e)));
      return OTHER_FAIL;
   } catch( const std::runtime_error& e ) {
      if( std::string(e.what()) == "database dirty flag set" ) {
         elog( "database dirty flag set (likely due to unclean shutdown): replay required" );
         return DATABASE_DIRTY;
      } else if( std::string(e.what()) == "database metadata dirty flag set" ) {
         elog( "database metadata dirty flag set (likely due to unclean shutdown): replay required" );
         return DATABASE_DIRTY;
      } else {
         elog( "${e}", ("e",e.what()));
      }
      return OTHER_FAIL;
   } catch( const std::exception& e ) {
      elog("${e}", ("e",e.what()));
      return OTHER_FAIL;
   } catch( ... ) {
      elog("unknown exception");
      return OTHER_FAIL;
   }

   ilog("nodeos successfully exiting");
   return SUCCESS;
}
<commit_msg>Do not name main thread since some tests expect it to be nodeos<commit_after>/**
 *  @file
 *  @copyright defined in eosio/LICENSE.txt
 */
#include <appbase/application.hpp>

#include <eosio/chain_plugin/chain_plugin.hpp>
#include <eosio/http_plugin/http_plugin.hpp>
#include <eosio/net_plugin/net_plugin.hpp>
#include <eosio/producer_plugin/producer_plugin.hpp>

#include <fc/log/logger_config.hpp>
#include <fc/log/appender.hpp>
#include <fc/exception/exception.hpp>

#include <boost/dll/runtime_symbol_info.hpp>
#include <boost/exception/diagnostic_information.hpp>

#include "config.hpp"

using namespace appbase;
using namespace eosio;

namespace fc {
   std::unordered_map<std::string,appender::ptr>& get_appender_map();
}

namespace detail {

void configure_logging(const bfs::path& config_path)
{
   try {
      try {
         fc::configure_logging(config_path);
      } catch (...) {
         elog("Error reloading logging.json");
         throw;
      }
   } catch (const fc::exception& e) {
      elog("${e}", ("e",e.to_detail_string()));
   } catch (const boost::exception& e) {
      elog("${e}", ("e",boost::diagnostic_information(e)));
   } catch (const std::exception& e) {
      elog("${e}", ("e",e.what()));
   } catch (...) {
      // empty
   }
}

} // namespace detail

void logging_conf_handler()
{
   ilog("Received HUP.  Reloading logging configuration.");
   auto config_path = app().get_logging_conf();
   if(fc::exists(config_path))
      ::detail::configure_logging(config_path);
   for(auto iter : fc::get_appender_map())
      iter.second->initialize(app().get_io_service());
}

void initialize_logging()
{
   auto config_path = app().get_logging_conf();
   if(fc::exists(config_path))
     fc::configure_logging(config_path); // intentionally allowing exceptions to escape
   for(auto iter : fc::get_appender_map())
     iter.second->initialize(app().get_io_service());

   app().set_sighup_callback(logging_conf_handler);
}

enum return_codes {
   OTHER_FAIL        = -2,
   INITIALIZE_FAIL   = -1,
   SUCCESS           = 0,
   BAD_ALLOC         = 1,
   DATABASE_DIRTY    = 2,
   FIXED_REVERSIBLE  = 3,
   EXTRACTED_GENESIS = 4,
   NODE_MANAGEMENT_SUCCESS = 5
};

int main(int argc, char** argv)
{
   try {
      app().set_version(eosio::nodeos::config::version);

      auto root = fc::app_path();
      app().set_default_data_dir(root / "eosio/nodeos/data" );
      app().set_default_config_dir(root / "eosio/nodeos/config" );
      http_plugin::set_defaults({
         .default_unix_socket_path = "",
         .default_http_port = 8888
      });
      if(!app().initialize<chain_plugin, net_plugin, producer_plugin>(argc, argv))
         return INITIALIZE_FAIL;
      initialize_logging();
      ilog("nodeos version ${ver}", ("ver", app().version_string()));
      ilog("eosio root is ${root}", ("root", root.string()));
      ilog("nodeos using configuration file ${c}", ("c", app().full_config_file_path().string()));
      ilog("nodeos data directory is ${d}", ("d", app().data_dir().string()));
      app().startup();
      app().exec();
   } catch( const extract_genesis_state_exception& e ) {
      return EXTRACTED_GENESIS;
   } catch( const fixed_reversible_db_exception& e ) {
      return FIXED_REVERSIBLE;
   } catch( const node_management_success& e ) {
      return NODE_MANAGEMENT_SUCCESS;
   } catch( const fc::exception& e ) {
      if( e.code() == fc::std_exception_code ) {
         if( e.top_message().find( "database dirty flag set" ) != std::string::npos ) {
            elog( "database dirty flag set (likely due to unclean shutdown): replay required" );
            return DATABASE_DIRTY;
         } else if( e.top_message().find( "database metadata dirty flag set" ) != std::string::npos ) {
            elog( "database metadata dirty flag set (likely due to unclean shutdown): replay required" );
            return DATABASE_DIRTY;
         }
      }
      elog( "${e}", ("e", e.to_detail_string()));
      return OTHER_FAIL;
   } catch( const boost::interprocess::bad_alloc& e ) {
      elog("bad alloc");
      return BAD_ALLOC;
   } catch( const boost::exception& e ) {
      elog("${e}", ("e",boost::diagnostic_information(e)));
      return OTHER_FAIL;
   } catch( const std::runtime_error& e ) {
      if( std::string(e.what()) == "database dirty flag set" ) {
         elog( "database dirty flag set (likely due to unclean shutdown): replay required" );
         return DATABASE_DIRTY;
      } else if( std::string(e.what()) == "database metadata dirty flag set" ) {
         elog( "database metadata dirty flag set (likely due to unclean shutdown): replay required" );
         return DATABASE_DIRTY;
      } else {
         elog( "${e}", ("e",e.what()));
      }
      return OTHER_FAIL;
   } catch( const std::exception& e ) {
      elog("${e}", ("e",e.what()));
      return OTHER_FAIL;
   } catch( ... ) {
      elog("unknown exception");
      return OTHER_FAIL;
   }

   ilog("nodeos successfully exiting");
   return SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 The Imaging Source Europe GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "devicelibrary.h"

#include "AravisDevice.h"
#include "aravis_utils.h"

#include <cstring>

DeviceInterface* open_device (const struct tcam_device_info* device)
{
    return new AravisDevice(DeviceInfo(*device));
}

size_t get_device_list_size ()
{
    auto vec = get_gige_device_list();
    return vec.size();
}

/**
 * @return number of copied device_infos
 */
size_t get_device_list (struct tcam_device_info* array, size_t array_size)
{
    auto vec = get_gige_device_list();

    if (vec.size() > array_size)
    {
        return 0;
    }

    for (const auto v : vec)
    {
        auto i = v.get_info();
        memcpy(array, &i, sizeof(struct tcam_device_info));
        array++;
    }

    return vec.size();
}

struct libinfo_v1* get_library_functions_v1 ()
{
    struct libinfo_v1* info = new libinfo_v1();

    info->open_device = &open_device;
    info->get_device_list_size = &get_device_list_size;
    info->get_device_list = &get_device_list;

    return info;
}
<commit_msg>Switch aravislibrary::get_device_list_size to get_gige_device_count<commit_after>/*
 * Copyright 2016 The Imaging Source Europe GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "devicelibrary.h"

#include "AravisDevice.h"
#include "aravis_utils.h"

#include <cstring>

DeviceInterface* open_device (const struct tcam_device_info* device)
{
    return new AravisDevice(DeviceInfo(*device));
}

size_t get_device_list_size ()
{
    return get_gige_device_count();
}

/**
 * @return number of copied device_infos
 */
size_t get_device_list (struct tcam_device_info* array, size_t array_size)
{
    auto vec = get_gige_device_list();

    if (vec.size() > array_size)
    {
        return 0;
    }

    for (const auto v : vec)
    {
        auto i = v.get_info();
        memcpy(array, &i, sizeof(struct tcam_device_info));
        array++;
    }

    return vec.size();
}

struct libinfo_v1* get_library_functions_v1 ()
{
    struct libinfo_v1* info = new libinfo_v1();

    info->open_device = &open_device;
    info->get_device_list_size = &get_device_list_size;
    info->get_device_list = &get_device_list;

    return info;
}
<|endoftext|>


<commit_before>#include "main.h"
#include "AppDelegate.h"
#include "CCEGLView.h"

USING_NS_CC;

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // create the application instance
    AppDelegate app;
    CCEGLView* eglView = CCEGLView::sharedOpenGLView();
    eglView->setViewName("CowboyScene");
    eglView->setFrameSize(480, 320);
    return CCApplication::sharedApplication()->run();
}
<commit_msg>DemoCowboy: fix window size for win32<commit_after>#include "main.h"
#include "AppDelegate.h"
#include "CCEGLView.h"

USING_NS_CC;

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // create the application instance
    AppDelegate app;
    CCEGLView* eglView = CCEGLView::sharedOpenGLView();
    eglView->setViewName("CowboyScene");
    eglView->setFrameSize(960, 640);
    return CCApplication::sharedApplication()->run();
}
<|endoftext|>


<commit_before>// Project specific
#include <Manager/TriggerManager.hpp>
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <DoremiEngine/Physics/Include/RigidBodyManager.hpp>
#include <EntityComponent/EntityHandler.hpp>
#include <EventHandler/EventHandler.hpp>
#include <EventHandler/Events/TriggerEvent.hpp>
#include <EntityComponent/Components/TriggerComponent.hpp>
#include <EntityComponent/Components/TransformComponent.hpp>

// Third party

// Standard
#include <iostream>
using namespace std;

namespace Doremi
{
    namespace Core
    {
        TriggerManager::TriggerManager(const DoremiEngine::Core::SharedContext& p_sharedContext) : Manager(p_sharedContext, "TriggerManager") {}

        TriggerManager::~TriggerManager() {}

        void TriggerManager::Update(double p_dt)
        {
            // TODOXX If a trigger has the same wall as another trigger it acts weird. It will(tried it once) trigger one triggertype on the way out
            // and one on the
            // way in
            // Loop through all entities
            const size_t length = EntityHandler::GetInstance().GetLastEntityIndex();
            for(size_t i = 0; i < length; i++)
            {
                // collisionTriggerPairs[k].firstID
                // Check that the current entity has the relevant components
                if(EntityHandler::GetInstance().HasComponents(i, (int)ComponentType::Trigger | (int)ComponentType::Transform | (int)ComponentType::RigidBody))
                {
                    std::vector<DoremiEngine::Physics::CollisionPair> collisionTriggerPairs = m_sharedContext.GetPhysicsModule().GetTriggerPairs();
                    size_t collisionListLength = collisionTriggerPairs.size();
                    for(size_t k = 0; k < collisionListLength; ++k)
                    {
                        if(i == collisionTriggerPairs[k].firstID)
                        {

                            TriggerEventStruct* myEvent = new TriggerEventStruct();
                            TriggerComponent* triggComp = EntityHandler::GetInstance().GetComponentFromStorage<TriggerComponent>(i);
                            myEvent->triggerType = triggComp->triggerType;
                            myEvent->entityID = collisionTriggerPairs[k].secondID;
                            EventHandler::GetInstance()->BroadcastEvent(myEvent);
                        }
                        else
                        {
                            // DO nathiiing
                        }
                    }
                }
                else
                {
                    // do nuting
                }
            }
        }
        void TriggerManager::OnEvent(Event* p_event)
        {
            // Check to see what event was received and do something with it (Might be changed to callback functions instead)
            switch(p_event->eventType)
            {

                default:
                    break;
            }
        }
    }
}<commit_msg>Added comments to triggermanager.cpp<commit_after>// Project specific
#include <Manager/TriggerManager.hpp>
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <DoremiEngine/Physics/Include/RigidBodyManager.hpp>
#include <EntityComponent/EntityHandler.hpp>
#include <EventHandler/EventHandler.hpp>
#include <EventHandler/Events/TriggerEvent.hpp>
#include <EntityComponent/Components/TriggerComponent.hpp>
#include <EntityComponent/Components/TransformComponent.hpp>

// Third party

// Standard
#include <iostream>
using namespace std;

namespace Doremi
{
    namespace Core
    {
        TriggerManager::TriggerManager(const DoremiEngine::Core::SharedContext& p_sharedContext) : Manager(p_sharedContext, "TriggerManager") {}

        TriggerManager::~TriggerManager() {}

        void TriggerManager::Update(double p_dt)
        {
            // TODOXX If a trigger has the same wall as another trigger it acts weird. It will(tried it once) trigger one triggertype on the way out
            // and one on the
            // way in
            // Loop through all entities
            const size_t length = EntityHandler::GetInstance().GetLastEntityIndex();
            for(size_t i = 0; i < length; i++)
            {
                // Check that the current entity has the relevant components
                if(EntityHandler::GetInstance().HasComponents(i, (int)ComponentType::Trigger | (int)ComponentType::Transform | (int)ComponentType::RigidBody))
                {

                    // Get the collisionpairs from physicmodule
                    std::vector<DoremiEngine::Physics::CollisionPair> collisionTriggerPairs = m_sharedContext.GetPhysicsModule().GetTriggerPairs();
                    size_t collisionListLength = collisionTriggerPairs.size();
                    for(size_t k = 0; k < collisionListLength; ++k)
                    {
                        // The first id will always be the trigger.
                        if(i == collisionTriggerPairs[k].firstID)
                        {
                            // setting up an event to broadcast the triggertype from the component trigger.
                            TriggerEventStruct* myEvent = new TriggerEventStruct();
                            TriggerComponent* triggComp = EntityHandler::GetInstance().GetComponentFromStorage<TriggerComponent>(i);
                            myEvent->triggerType = triggComp->triggerType;
                            myEvent->entityID = collisionTriggerPairs[k].secondID;
                            EventHandler::GetInstance()->BroadcastEvent(myEvent);
                        }
                        else
                        {
                            // DO nathiiing
                        }
                    }
                }
                else
                {
                    // do nuting
                }
            }
        }
        void TriggerManager::OnEvent(Event* p_event)
        {
            // Check to see what event was received and do something with it (Might be changed to callback functions instead)
            switch(p_event->eventType)
            {

                default:
                    break;
            }
        }
    }
}<|endoftext|>


<commit_before>/*
 * Copyright (C) 2019-present ScyllaDB
 */

#include "build_id.hh"
#include <fmt/ostream.h>
#include <link.h>
#include <seastar/core/align.hh>
#include <sstream>
#include <cassert>

using namespace seastar;

static const Elf64_Nhdr* get_nt_build_id(dl_phdr_info* info) {
    auto base = info->dlpi_addr;
    const auto* h = info->dlpi_phdr;
    auto num_headers = info->dlpi_phnum;
    for (int i = 0; i != num_headers; ++i, ++h) {
        if (h->p_type != PT_NOTE) {
            continue;
        }

        auto* p = reinterpret_cast<const char*>(base + h->p_vaddr);
        auto* e = p + h->p_memsz;
        while (p != e) {
            const auto* n = reinterpret_cast<const Elf64_Nhdr*>(p);
            if (n->n_type == NT_GNU_BUILD_ID) {
                return n;
            }

            p += sizeof(Elf64_Nhdr);

            p += n->n_namesz;
            p = align_up(p, 4);

            p += n->n_descsz;
            p = align_up(p, 4);
        }
    }

    assert(0 && "no NT_GNU_BUILD_ID note");
}

static int callback(dl_phdr_info* info, size_t size, void* data) {
    std::string& ret = *(std::string*)data;
    std::ostringstream os;

    // The first DSO is always the main program, which has an empty name.
    assert(strlen(info->dlpi_name) == 0);

    auto* n = get_nt_build_id(info);
    auto* p = reinterpret_cast<const unsigned char*>(n);

    p += sizeof(Elf64_Nhdr);

    p += n->n_namesz;
    p = align_up(p, 4);

    auto* desc = p;
    auto* desc_end = p + n->n_descsz;
    while (desc < desc_end) {
        fmt::print(os, "{:02x}", *desc++);
    }
    ret = os.str();
    return 1;
}

std::string get_build_id() {
    std::string ret;
    int r = dl_iterate_phdr(callback, &ret);
    assert(r == 1);
    return ret;
}
<commit_msg>build_id: cache the value<commit_after>/*
 * Copyright (C) 2019-present ScyllaDB
 */

#include "build_id.hh"
#include <fmt/ostream.h>
#include <link.h>
#include <seastar/core/align.hh>
#include <sstream>
#include <cassert>

using namespace seastar;

static const Elf64_Nhdr* get_nt_build_id(dl_phdr_info* info) {
    auto base = info->dlpi_addr;
    const auto* h = info->dlpi_phdr;
    auto num_headers = info->dlpi_phnum;
    for (int i = 0; i != num_headers; ++i, ++h) {
        if (h->p_type != PT_NOTE) {
            continue;
        }

        auto* p = reinterpret_cast<const char*>(base + h->p_vaddr);
        auto* e = p + h->p_memsz;
        while (p != e) {
            const auto* n = reinterpret_cast<const Elf64_Nhdr*>(p);
            if (n->n_type == NT_GNU_BUILD_ID) {
                return n;
            }

            p += sizeof(Elf64_Nhdr);

            p += n->n_namesz;
            p = align_up(p, 4);

            p += n->n_descsz;
            p = align_up(p, 4);
        }
    }

    assert(0 && "no NT_GNU_BUILD_ID note");
}

static int callback(dl_phdr_info* info, size_t size, void* data) {
    std::string& ret = *(std::string*)data;
    std::ostringstream os;

    // The first DSO is always the main program, which has an empty name.
    assert(strlen(info->dlpi_name) == 0);

    auto* n = get_nt_build_id(info);
    auto* p = reinterpret_cast<const unsigned char*>(n);

    p += sizeof(Elf64_Nhdr);

    p += n->n_namesz;
    p = align_up(p, 4);

    auto* desc = p;
    auto* desc_end = p + n->n_descsz;
    while (desc < desc_end) {
        fmt::print(os, "{:02x}", *desc++);
    }
    ret = os.str();
    return 1;
}

static std::string really_get_build_id() {
    std::string ret;
    int r = dl_iterate_phdr(callback, &ret);
    assert(r == 1);
    return ret;
}

std::string get_build_id() {
    static thread_local std::string cache;
    if (cache.empty()) {
        cache = really_get_build_id();
    }
    return cache;
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#define EIGEN_NO_STATIC_ASSERT

#include "main.h"

template<typename MatrixType> void adjoint(const MatrixType& m)
{
  /* this test covers the following files:
     Transpose.h Conjugate.h Dot.h
  */
  using std::abs;
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols),
             square = SquareMatrixType::Random(rows, rows);
  VectorType v1 = VectorType::Random(rows),
             v2 = VectorType::Random(rows),
             v3 = VectorType::Random(rows),
             vzero = VectorType::Zero(rows);

  Scalar s1 = internal::random<Scalar>(),
         s2 = internal::random<Scalar>();

  // check basic compatibility of adjoint, transpose, conjugate
  VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(),    m1);
  VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(),    m1);

  // check multiplicative behavior
  VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(),           m2.adjoint() * m1);
  VERIFY_IS_APPROX((s1 * m1).adjoint(),                     internal::conj(s1) * m1.adjoint());

  // check basic properties of dot, norm, norm2
  typedef typename NumTraits<Scalar>::Real RealScalar;

  RealScalar ref = NumTraits<Scalar>::IsInteger ? RealScalar(0) : (std::max)((s1 * v1 + s2 * v2).norm(),v3.norm());
  VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3),     internal::conj(s1) * v1.dot(v3) + internal::conj(s2) * v2.dot(v3), ref));
  VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2),       s1*v3.dot(v1)+s2*v3.dot(v2), ref));
  VERIFY_IS_APPROX(internal::conj(v1.dot(v2)),               v2.dot(v1));
  VERIFY_IS_APPROX(internal::real(v1.dot(v1)),                v1.squaredNorm());
  if(!NumTraits<Scalar>::IsInteger) {
    VERIFY_IS_APPROX(v1.squaredNorm(),                v1.norm() * v1.norm());
    // check normalized() and normalize()
    VERIFY_IS_APPROX(v1, v1.norm() * v1.normalized());
    v3 = v1;
    v3.normalize();
    VERIFY_IS_APPROX(v1, v1.norm() * v3);
    VERIFY_IS_APPROX(v3, v1.normalized());
    VERIFY_IS_APPROX(v3.norm(), RealScalar(1));
  }
  VERIFY_IS_MUCH_SMALLER_THAN(abs(vzero.dot(v1)),  static_cast<RealScalar>(1));

  // check compatibility of dot and adjoint

  ref = NumTraits<Scalar>::IsInteger ? 0 : (std::max)((std::max)(v1.norm(),v2.norm()),(std::max)((square * v2).norm(),(square.adjoint() * v1).norm()));
  VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), ref));

  // like in testBasicStuff, test operator() to check const-qualification
  Index r = internal::random<Index>(0, rows-1),
      c = internal::random<Index>(0, cols-1);
  VERIFY_IS_APPROX(m1.conjugate()(r,c), internal::conj(m1(r,c)));
  VERIFY_IS_APPROX(m1.adjoint()(c,r), internal::conj(m1(r,c)));

  if(!NumTraits<Scalar>::IsInteger)
  {
    // check that Random().normalized() works: tricky as the random xpr must be evaluated by
    // normalized() in order to produce a consistent result.
    VERIFY_IS_APPROX(VectorType::Random(rows).normalized().norm(), RealScalar(1));
  }

  // check inplace transpose
  m3 = m1;
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1.transpose());
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1);

  // check inplace adjoint
  m3 = m1;
  m3.adjointInPlace();
  VERIFY_IS_APPROX(m3,m1.adjoint());
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1.conjugate());

  // check mixed dot product
  typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
  RealVectorType rv1 = RealVectorType::Random(rows);
  VERIFY_IS_APPROX(v1.dot(rv1.template cast<Scalar>()), v1.dot(rv1));
  VERIFY_IS_APPROX(rv1.template cast<Scalar>().dot(v1), rv1.dot(v1));
}

void test_adjoint()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( adjoint(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( adjoint(Matrix3d()) );
    CALL_SUBTEST_3( adjoint(Matrix4f()) );
    CALL_SUBTEST_4( adjoint(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
    CALL_SUBTEST_5( adjoint(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( adjoint(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  // test a large static matrix only once
  CALL_SUBTEST_7( adjoint(Matrix<float, 100, 100>()) );

#ifdef EIGEN_TEST_PART_4
  {
    MatrixXcf a(10,10), b(10,10);
    VERIFY_RAISES_ASSERT(a = a.transpose());
    VERIFY_RAISES_ASSERT(a = a.transpose() + b);
    VERIFY_RAISES_ASSERT(a = b + a.transpose());
    VERIFY_RAISES_ASSERT(a = a.conjugate().transpose());
    VERIFY_RAISES_ASSERT(a = a.adjoint());
    VERIFY_RAISES_ASSERT(a = a.adjoint() + b);
    VERIFY_RAISES_ASSERT(a = b + a.adjoint());

    // no assertion should be triggered for these cases:
    a.transpose() = a.transpose();
    a.transpose() += a.transpose();
    a.transpose() += a.transpose() + b;
    a.transpose() = a.adjoint();
    a.transpose() += a.adjoint();
    a.transpose() += a.adjoint() + b;
  }
#endif
}

<commit_msg>Update adjoint unit test to avoid instantiating sqrt(int)<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#define EIGEN_NO_STATIC_ASSERT

#include "main.h"

template<bool IsInteger> struct adjoint_specific;

template<> struct adjoint_specific<true> {
  template<typename Vec, typename Mat, typename Scalar>
  static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {
    VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3),     internal::conj(s1) * v1.dot(v3) + internal::conj(s2) * v2.dot(v3), 0));
    VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2),       s1*v3.dot(v1)+s2*v3.dot(v2), 0));

    // check compatibility of dot and adjoint
    VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), 0));
  }
};

template<> struct adjoint_specific<false> {
  template<typename Vec, typename Mat, typename Scalar>
  static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {
    typedef typename NumTraits<Scalar>::Real RealScalar;

    RealScalar ref = NumTraits<Scalar>::IsInteger ? RealScalar(0) : (std::max)((s1 * v1 + s2 * v2).norm(),v3.norm());
    VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3),     internal::conj(s1) * v1.dot(v3) + internal::conj(s2) * v2.dot(v3), ref));
    VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2),       s1*v3.dot(v1)+s2*v3.dot(v2), ref));

    VERIFY_IS_APPROX(v1.squaredNorm(),                v1.norm() * v1.norm());
    // check normalized() and normalize()
    VERIFY_IS_APPROX(v1, v1.norm() * v1.normalized());
    v3 = v1;
    v3.normalize();
    VERIFY_IS_APPROX(v1, v1.norm() * v3);
    VERIFY_IS_APPROX(v3, v1.normalized());
    VERIFY_IS_APPROX(v3.norm(), RealScalar(1));

    // check compatibility of dot and adjoint
    ref = NumTraits<Scalar>::IsInteger ? 0 : (std::max)((std::max)(v1.norm(),v2.norm()),(std::max)((square * v2).norm(),(square.adjoint() * v1).norm()));
    VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), ref));

    // check that Random().normalized() works: tricky as the random xpr must be evaluated by
    // normalized() in order to produce a consistent result.
    VERIFY_IS_APPROX(Vec::Random(v1.size()).normalized().norm(), RealScalar(1));
  }
};

template<typename MatrixType> void adjoint(const MatrixType& m)
{
  /* this test covers the following files:
     Transpose.h Conjugate.h Dot.h
  */
  using std::abs;
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols),
             square = SquareMatrixType::Random(rows, rows);
  VectorType v1 = VectorType::Random(rows),
             v2 = VectorType::Random(rows),
             v3 = VectorType::Random(rows),
             vzero = VectorType::Zero(rows);

  Scalar s1 = internal::random<Scalar>(),
         s2 = internal::random<Scalar>();

  // check basic compatibility of adjoint, transpose, conjugate
  VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(),    m1);
  VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(),    m1);

  // check multiplicative behavior
  VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(),           m2.adjoint() * m1);
  VERIFY_IS_APPROX((s1 * m1).adjoint(),                     internal::conj(s1) * m1.adjoint());

  // check basic properties of dot, squaredNorm
  VERIFY_IS_APPROX(internal::conj(v1.dot(v2)),               v2.dot(v1));
  VERIFY_IS_APPROX(internal::real(v1.dot(v1)),               v1.squaredNorm());

  adjoint_specific<NumTraits<Scalar>::IsInteger>::run(v1, v2, v3, square, s1, s2);

  VERIFY_IS_MUCH_SMALLER_THAN(abs(vzero.dot(v1)),  static_cast<RealScalar>(1));

  // like in testBasicStuff, test operator() to check const-qualification
  Index r = internal::random<Index>(0, rows-1),
      c = internal::random<Index>(0, cols-1);
  VERIFY_IS_APPROX(m1.conjugate()(r,c), internal::conj(m1(r,c)));
  VERIFY_IS_APPROX(m1.adjoint()(c,r), internal::conj(m1(r,c)));

  // check inplace transpose
  m3 = m1;
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1.transpose());
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1);

  // check inplace adjoint
  m3 = m1;
  m3.adjointInPlace();
  VERIFY_IS_APPROX(m3,m1.adjoint());
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1.conjugate());

  // check mixed dot product
  typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
  RealVectorType rv1 = RealVectorType::Random(rows);
  VERIFY_IS_APPROX(v1.dot(rv1.template cast<Scalar>()), v1.dot(rv1));
  VERIFY_IS_APPROX(rv1.template cast<Scalar>().dot(v1), rv1.dot(v1));
}

void test_adjoint()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( adjoint(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( adjoint(Matrix3d()) );
    CALL_SUBTEST_3( adjoint(Matrix4f()) );
    CALL_SUBTEST_4( adjoint(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
    CALL_SUBTEST_5( adjoint(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( adjoint(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  // test a large static matrix only once
  CALL_SUBTEST_7( adjoint(Matrix<float, 100, 100>()) );

#ifdef EIGEN_TEST_PART_4
  {
    MatrixXcf a(10,10), b(10,10);
    VERIFY_RAISES_ASSERT(a = a.transpose());
    VERIFY_RAISES_ASSERT(a = a.transpose() + b);
    VERIFY_RAISES_ASSERT(a = b + a.transpose());
    VERIFY_RAISES_ASSERT(a = a.conjugate().transpose());
    VERIFY_RAISES_ASSERT(a = a.adjoint());
    VERIFY_RAISES_ASSERT(a = a.adjoint() + b);
    VERIFY_RAISES_ASSERT(a = b + a.adjoint());

    // no assertion should be triggered for these cases:
    a.transpose() = a.transpose();
    a.transpose() += a.transpose();
    a.transpose() += a.transpose() + b;
    a.transpose() = a.adjoint();
    a.transpose() += a.adjoint();
    a.transpose() += a.adjoint() + b;
  }
#endif
}

<|endoftext|>


<commit_before>
////using the C++ API

#include "zorba/zorba_api.h"

//for debug
//#include "../src/compiler/parser/xquery_driver.h"
#include "../src/util/logging/loggermanager.hh"
#include "timer.h"
#include "error_display.h"
#include "zorba/util/properties.h"

#ifdef WIN32
	#include "../src/util/win32/compatib_defs.h"
#endif

#include <fstream>
#include <iostream>
#include <iomanip>

using namespace xqp;
using namespace std;

int apitest_alert_callback(ZorbaAlert *alert_mess,
                           XQuery*  current_xquery,
                           XQueryExecution* current_xqueryresult,
                           void *param)
{
#ifndef NDEBUG
  if((alert_mess->alert_type != ZorbaAlert::USER_ERROR_ALERT) &&
    (alert_mess->alert_type != ZorbaAlert::USER_TRACE_ALERT))
  {
    cerr << g_error_in_file << " : " << g_error_at_line << endl;
  }
#endif
  cerr << endl;

  DisplayOneAlert(alert_mess);

  cerr.flush();

  return -1;
}

void set_var (string name, string val, DynamicQueryContext_t dctx, XQueryExecution_t result) {
  if (name [name.size () - 1] == ':' && dctx != NULL) {
    dctx->SetVariable (name.substr (0, name.size () - 1), xqp_string (val));
  } else if (name [name.size () - 1] != ':' && result != NULL) {
    ifstream is (val.c_str ());
    assert (is);
    result->SetVariable (name, is);
  }
}

#ifndef _WIN32_WCE
int main(int argc, char* argv[])
#else
int _tmain(int argc, _TCHAR* argv[])
#endif
{
  Timer timer;
  timer.start();

  if (!Properties::load(argc,argv))
    return 1;

  Properties* lProp = Properties::instance();

  xqp::LoggerManager::logmanager()->setLoggerConfig("#1#logging.log");

  ofstream* resultFile = NULL;
  string    query_text = "1+2";  // the default query if no file or query is specified

#ifndef NDEBUG
  g_abort_when_fatal_error = lProp->abortWhenFatalError();
#endif

  const char* fname = lProp->getQuery().c_str();
#ifndef UNICODE
  if (lProp->inlineQuery())
    query_text = fname;
#endif

#ifdef UNICODE
  if(! lProp->inlineQuery())
  {
    char  testfile[1024];
    WideCharToMultiByte(CP_ACP, 0, // or CP_UTF8
                        *argv, -1,
                        testfile, sizeof(testfile)/sizeof(char),
                        NULL, NULL);
    fname = testfile;
  }
#endif
  if(! lProp->inlineQuery())
  {
    // read the file
    ifstream  qfile(fname);

    if(!qfile.is_open())
      query_text = fname;
    else {
    string temp;
      query_text = "";

      // warning: this method of reading a file might trim the
      // whitespace at the end of lines
      while (getline(qfile, temp)) {
        if (query_text != "")
          query_text += "\n";

        query_text += temp;
      }
    }
  }

  if (lProp->printQuery())
    std::cout << query_text << std::endl;

  /// now start the zorba engine

  ZorbaEngine& zorba_factory = ZorbaEngine::getInstance();

  /// thread specific

  zorba_factory.initThread();

  /// register the alerts callback
  ZorbaAlertsManager& errmanager = zorba_factory.getAlertsManagerForCurrentThread();

  errmanager.RegisterAlertCallback(apitest_alert_callback, (void*)101);

  StaticQueryContext_t sctx1;

  sctx1 = zorba_factory.createStaticContext();
  sctx1->AddCollation("http://www.flworfound.org/apitest/coll1", "en");
  sctx1->AddCollation("http://www.flworfound.org/apitest/coll2", "de");
  sctx1->AddCollation("http://www.flworfound.org/apitest/coll2", "fr");
  sctx1->SetOrderingMode(StaticQueryContext::unordered);
  StaticQueryContext::xpath1_0compatib_mode_t   default_compatib_mode;
  default_compatib_mode = sctx1->GetXPath1_0CompatibMode();

  vector<pair <string, string> > ext_vars = lProp->getExternalVars ();

  XQuery_t query;
  XQueryExecution_t result = NULL;

  DynamicQueryContext_t dctx = zorba_factory.createDynamicContext ();
  for (vector<pair <string, string> >::iterator iter = ext_vars.begin ();
       iter != ext_vars.end (); iter++)
    set_var (iter->first, iter->second, dctx, NULL);

  // create a compiled query
  query = zorba_factory.createQuery(query_text.c_str(), sctx1);

  if(query.isNull())
  {
    goto DisplayErrorsAndExit;
  }

  result = query->createExecution(dctx);
  if(result.isNull())
  {
    goto DisplayErrorsAndExit;
  }

  for (vector<pair <string, string> >::iterator iter = ext_vars.begin ();
       iter != ext_vars.end (); iter++)
    set_var (iter->first, iter->second, NULL, result);

  result->setAlertsParam(result.get_ptr());///to be passed to alerts callback when error occurs

  if (lProp->useResultFile())
    resultFile = new ofstream(lProp->getResultFile().c_str());

  if (lProp->useSerializer()) {
    if (lProp->useResultFile()) {
      result->serialize(*resultFile);
      // endl should not be sent when serializing!
    }
    else result->serialize(std::cout);
  }
  else {
    while( true )
    {
      Item_t it = result->next();
      if(it == NULL)
        break;

      if (resultFile != NULL)
        *resultFile << it->show() <<  endl;
      else
        cout << it->show() << endl;
    }
  }
  if(result->isError()) {
    goto DisplayErrorsAndExit;
  }

  // delete result;
  // delete query;
  // zorba_factory.destroyQuery(query);

  zorba_factory.uninitThread();
  zorba_factory.shutdown();

  timer.end();

  if (lProp->printTime())
    timer.print(cout);

  if (resultFile != NULL) {
    resultFile->close();
    delete resultFile;
  }

  return 0;

DisplayErrorsAndExit:
  cerr << endl << "Error list:" << endl;

  DisplayErrorListForCurrentThread();

  zorba_factory.uninitThread();
  zorba_factory.shutdown();

  timer.end();
  if (lProp->printTime())
    timer.print(cout);

  return 0;
}

<commit_msg>Removed apitest "feature" that assumes a file name is an actual query when the file cannot be open.<commit_after>
////using the C++ API

#include "zorba/zorba_api.h"

//for debug
//#include "../src/compiler/parser/xquery_driver.h"
#include "../src/util/logging/loggermanager.hh"
#include "timer.h"
#include "error_display.h"
#include "zorba/util/properties.h"

#ifdef WIN32
	#include "../src/util/win32/compatib_defs.h"
#endif

#include <fstream>
#include <iostream>
#include <iomanip>

using namespace xqp;
using namespace std;

int apitest_alert_callback(ZorbaAlert *alert_mess,
                           XQuery*  current_xquery,
                           XQueryExecution* current_xqueryresult,
                           void *param)
{
#ifndef NDEBUG
  if((alert_mess->alert_type != ZorbaAlert::USER_ERROR_ALERT) &&
    (alert_mess->alert_type != ZorbaAlert::USER_TRACE_ALERT))
  {
    cerr << g_error_in_file << " : " << g_error_at_line << endl;
  }
#endif
  cerr << endl;

  DisplayOneAlert(alert_mess);

  cerr.flush();

  return -1;
}

void set_var (string name, string val, DynamicQueryContext_t dctx, XQueryExecution_t result) {
  if (name [name.size () - 1] == ':' && dctx != NULL) {
    dctx->SetVariable (name.substr (0, name.size () - 1), xqp_string (val));
  } else if (name [name.size () - 1] != ':' && result != NULL) {
    ifstream is (val.c_str ());
    assert (is);
    result->SetVariable (name, is);
  }
}

#ifndef _WIN32_WCE
int main(int argc, char* argv[])
#else
int _tmain(int argc, _TCHAR* argv[])
#endif
{
  Timer timer;
  timer.start();

  if (!Properties::load(argc,argv))
    return 1;

  Properties* lProp = Properties::instance();

  xqp::LoggerManager::logmanager()->setLoggerConfig("#1#logging.log");

  ofstream* resultFile = NULL;
  string    query_text = "1+2";  // the default query if no file or query is specified

#ifndef NDEBUG
  g_abort_when_fatal_error = lProp->abortWhenFatalError();
#endif

  const char* fname = lProp->getQuery().c_str();
#ifndef UNICODE
  if (lProp->inlineQuery())
    query_text = fname;
#endif

#ifdef UNICODE
  if(! lProp->inlineQuery())
  {
    char  testfile[1024];
    WideCharToMultiByte(CP_ACP, 0, // or CP_UTF8
                        *argv, -1,
                        testfile, sizeof(testfile)/sizeof(char),
                        NULL, NULL);
    fname = testfile;
  }
#endif
  if(! lProp->inlineQuery()) {
    // read the file
    ifstream  qfile(fname);
    assert (qfile);

    {
      string temp;
      query_text = "";

      // warning: this method of reading a file might trim the
      // whitespace at the end of lines
      while (getline(qfile, temp)) {
        if (query_text != "")
          query_text += "\n";

        query_text += temp;
      }
    }
  }

  if (lProp->printQuery())
    std::cout << query_text << std::endl;

  /// now start the zorba engine

  ZorbaEngine& zorba_factory = ZorbaEngine::getInstance();

  /// thread specific

  zorba_factory.initThread();

  /// register the alerts callback
  ZorbaAlertsManager& errmanager = zorba_factory.getAlertsManagerForCurrentThread();

  errmanager.RegisterAlertCallback(apitest_alert_callback, (void*)101);

  StaticQueryContext_t sctx1;

  sctx1 = zorba_factory.createStaticContext();
  sctx1->AddCollation("http://www.flworfound.org/apitest/coll1", "en");
  sctx1->AddCollation("http://www.flworfound.org/apitest/coll2", "de");
  sctx1->AddCollation("http://www.flworfound.org/apitest/coll2", "fr");
  sctx1->SetOrderingMode(StaticQueryContext::unordered);
  StaticQueryContext::xpath1_0compatib_mode_t   default_compatib_mode;
  default_compatib_mode = sctx1->GetXPath1_0CompatibMode();

  vector<pair <string, string> > ext_vars = lProp->getExternalVars ();

  XQuery_t query;
  XQueryExecution_t result = NULL;

  DynamicQueryContext_t dctx = zorba_factory.createDynamicContext ();
  for (vector<pair <string, string> >::iterator iter = ext_vars.begin ();
       iter != ext_vars.end (); iter++)
    set_var (iter->first, iter->second, dctx, NULL);

  // create a compiled query
  query = zorba_factory.createQuery(query_text.c_str(), sctx1);

  if(query.isNull())
  {
    goto DisplayErrorsAndExit;
  }

  result = query->createExecution(dctx);
  if(result.isNull())
  {
    goto DisplayErrorsAndExit;
  }

  for (vector<pair <string, string> >::iterator iter = ext_vars.begin ();
       iter != ext_vars.end (); iter++)
    set_var (iter->first, iter->second, NULL, result);

  result->setAlertsParam(result.get_ptr());///to be passed to alerts callback when error occurs

  if (lProp->useResultFile())
    resultFile = new ofstream(lProp->getResultFile().c_str());

  if (lProp->useSerializer()) {
    if (lProp->useResultFile()) {
      result->serialize(*resultFile);
      // endl should not be sent when serializing!
    }
    else result->serialize(std::cout);
  }
  else {
    while( true )
    {
      Item_t it = result->next();
      if(it == NULL)
        break;

      if (resultFile != NULL)
        *resultFile << it->show() <<  endl;
      else
        cout << it->show() << endl;
    }
  }
  if(result->isError()) {
    goto DisplayErrorsAndExit;
  }

  // delete result;
  // delete query;
  // zorba_factory.destroyQuery(query);

  zorba_factory.uninitThread();
  zorba_factory.shutdown();

  timer.end();

  if (lProp->printTime())
    timer.print(cout);

  if (resultFile != NULL) {
    resultFile->close();
    delete resultFile;
  }

  return 0;

DisplayErrorsAndExit:
  cerr << endl << "Error list:" << endl;

  DisplayErrorListForCurrentThread();

  zorba_factory.uninitThread();
  zorba_factory.shutdown();

  timer.end();
  if (lProp->printTime())
    timer.print(cout);

  return 0;
}

<|endoftext|>