<commit_before>/** @file
    SSL dynamic certificate loader
    Loads certificates into a hash table as they are requested

    @section license License

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you 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 <cstdio>
#include <memory.h>
#include <cinttypes>
#include "domain-tree.h"

// return true if comparable.  Return type of compare in relative parameter
// 0 if eq.  < 0 if node key is broader.  > 0 if parameter key is broader
bool
DomainNameTree::DomainNameNode::compare(std::string key, int &relative)
{
  size_t star_loc = key.find('*');
  bool is_wild    = false;

  if (star_loc != std::string::npos) {
    star_loc++;
    is_wild = true;
    key     = key.substr(star_loc);
  }

  return this->prunedCompare(key, relative, is_wild);
}

bool
DomainNameTree::DomainNameNode::prunedCompare(const std::string &key, int &relative, bool is_wild)
{
  if (key == this->key) {
    relative = 0;
    return true;
  } else {
    if (this->is_wild) {
      size_t loc = key.find(this->key);

      if (this->key == "") { // Match all
        relative = -1;
        return true;
      } else if (loc != std::string::npos) {
        // node key is in search key
        if ((key.length() - this->key.length()) == loc) {
          // And node key is at the end of search key
          relative = -1;
          return true;
        }
      }
    }
    if (is_wild) {
      if (key == "") { // Match all
        relative = 1;
        return true;
      } else {
        size_t loc = this->key.find(key);

        if (loc != std::string::npos) {
          if ((this->key.length() - key.length()) == loc) {
            relative = 1;
            return true;
          }
        }
      }
    }
  }

  return false;
}

DomainNameTree::DomainNameNode *
DomainNameTree::find(std::string key, bool best_match)
{
  DomainNameNode *retval = nullptr;
  DomainNameNode *first  = nullptr;
  size_t star_loc        = key.find('*');
  bool is_wild           = false;

  if (star_loc != std::string::npos) {
    key     = key.substr(star_loc + 1);
    is_wild = true;
  }

  bool set_iter                = false;
  DomainNameNode *current_node = root;
  std::deque<DomainNameNode *>::iterator sibPtr, endPtr;

  while (current_node != nullptr) {
    bool partial_match = false;
    int relative;

    if (current_node->prunedCompare(key, relative, is_wild)) {
      if (relative == 0) {
        retval = current_node;
        if (nullptr == first || retval->order < first->order) {
          first = retval;
        }
        current_node = nullptr;
        break;
      } else if (relative < 0) {
        retval        = current_node;
        partial_match = true;
        if (nullptr == first || retval->order < first->order) {
          first = retval;
        }
      }
    }
    if (partial_match) {
      // Check out the children, maybe there is something better there
      sibPtr   = current_node->children.begin();
      endPtr   = current_node->children.end();
      set_iter = true;
      if (sibPtr == endPtr) {
        break; // We are done
      }
      current_node = *(sibPtr++);
    } else { // No match here.  Look at next sibling?
      // Is there another sibling to look at?
      if (set_iter && sibPtr != endPtr) {
        current_node = *(sibPtr++);
      } else { // No more siblings to check, give it up.
        break;
      }
    }
  }

  return best_match ? retval : first;
}

DomainNameTree::DomainNameNode *
DomainNameTree::insert(std::string key, void *payload, int order)
{
  TSMutexLock(this->tree_mutex);
  DomainNameNode *retval = nullptr;
  DomainNameNode *node   = this->findBestMatch(key);
  int relative;

  if (node->compare(key, relative)) {
    size_t star_loc = key.find('*');
    bool is_wild    = false;

    if (star_loc != std::string::npos) {
      star_loc++;
      key     = key.substr(star_loc);
      is_wild = true;
    }
    if (relative < 0) {
      // Make a new node that is a child of node
      DomainNameNode *new_node = new DomainNameNode(key, payload, order, is_wild);

      new_node->parent = node;
      node->children.push_back(new_node);
      retval = new_node;
    } else if (relative > 0) {
      // Insert new node as parent of node
      DomainNameNode *new_node = new DomainNameNode(key, payload, order, is_wild);

      new_node->parent = node->parent;
      new_node->children.push_back(node);

      // Replace the node with new_node in the child list of the parent;
      for (std::deque<DomainNameNode *>::iterator iter = node->parent->children.begin(); iter != node->parent->children.end();
           ++iter) {
        if (*(iter) == node) {
          *(iter) = new_node;
        }
      }
      retval = new_node;
    } else {
      // Will not replace in the equal case
      // Unless this is the root node
      if (node->key == "" && node->order == 0x7fffffff) {
        node->key     = key;
        node->payload = payload;
        node->order   = order;
        retval        = node;
      }
    }
  }
  TSMutexUnlock(this->tree_mutex);

  return retval;
}
<commit_msg>Coverity CID #1267799 Resource leak Coverity CID #1241990 Resource leak<commit_after>/** @file
    SSL dynamic certificate loader
    Loads certificates into a hash table as they are requested

    @section license License

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you 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 <cstdio>
#include <memory.h>
#include <cinttypes>
#include "domain-tree.h"

// return true if comparable.  Return type of compare in relative parameter
// 0 if eq.  < 0 if node key is broader.  > 0 if parameter key is broader
bool
DomainNameTree::DomainNameNode::compare(std::string key, int &relative)
{
  size_t star_loc = key.find('*');
  bool is_wild    = false;

  if (star_loc != std::string::npos) {
    star_loc++;
    is_wild = true;
    key     = key.substr(star_loc);
  }

  return this->prunedCompare(key, relative, is_wild);
}

bool
DomainNameTree::DomainNameNode::prunedCompare(const std::string &key, int &relative, bool is_wild)
{
  if (key == this->key) {
    relative = 0;
    return true;
  } else {
    if (this->is_wild) {
      size_t loc = key.find(this->key);

      if (this->key == "") { // Match all
        relative = -1;
        return true;
      } else if (loc != std::string::npos) {
        // node key is in search key
        if ((key.length() - this->key.length()) == loc) {
          // And node key is at the end of search key
          relative = -1;
          return true;
        }
      }
    }
    if (is_wild) {
      if (key == "") { // Match all
        relative = 1;
        return true;
      } else {
        size_t loc = this->key.find(key);

        if (loc != std::string::npos) {
          if ((this->key.length() - key.length()) == loc) {
            relative = 1;
            return true;
          }
        }
      }
    }
  }

  return false;
}

DomainNameTree::DomainNameNode *
DomainNameTree::find(std::string key, bool best_match)
{
  DomainNameNode *retval = nullptr;
  DomainNameNode *first  = nullptr;
  size_t star_loc        = key.find('*');
  bool is_wild           = false;

  if (star_loc != std::string::npos) {
    key     = key.substr(star_loc + 1);
    is_wild = true;
  }

  bool set_iter                = false;
  DomainNameNode *current_node = root;
  std::deque<DomainNameNode *>::iterator sibPtr, endPtr;

  while (current_node != nullptr) {
    bool partial_match = false;
    int relative;

    if (current_node->prunedCompare(key, relative, is_wild)) {
      if (relative == 0) {
        retval = current_node;
        if (nullptr == first || retval->order < first->order) {
          first = retval;
        }
        current_node = nullptr;
        break;
      } else if (relative < 0) {
        retval        = current_node;
        partial_match = true;
        if (nullptr == first || retval->order < first->order) {
          first = retval;
        }
      }
    }
    if (partial_match) {
      // Check out the children, maybe there is something better there
      sibPtr   = current_node->children.begin();
      endPtr   = current_node->children.end();
      set_iter = true;
      if (sibPtr == endPtr) {
        break; // We are done
      }
      current_node = *(sibPtr++);
    } else { // No match here.  Look at next sibling?
      // Is there another sibling to look at?
      if (set_iter && sibPtr != endPtr) {
        current_node = *(sibPtr++);
      } else { // No more siblings to check, give it up.
        break;
      }
    }
  }

  return best_match ? retval : first;
}

DomainNameTree::DomainNameNode *
DomainNameTree::insert(std::string key, void *payload, int order)
{
  TSMutexLock(this->tree_mutex);
  DomainNameNode *retval = nullptr;
  DomainNameNode *node   = this->findBestMatch(key);
  int relative;

  if (node->compare(key, relative)) {
    size_t star_loc = key.find('*');
    bool is_wild    = false;

    if (star_loc != std::string::npos) {
      star_loc++;
      key     = key.substr(star_loc);
      is_wild = true;
    }
    if (relative < 0) {
      // Make a new node that is a child of node
      DomainNameNode *new_node = new DomainNameNode(key, payload, order, is_wild);

      new_node->parent = node;
      node->children.push_back(new_node);
      retval = new_node;
    } else if (relative > 0) {
      // Insert new node as parent of node
      DomainNameNode *new_node = new DomainNameNode(key, payload, order, is_wild);

      new_node->parent = node->parent;
      new_node->children.push_back(node);
      node->parent = new_node;

      // Replace the node with new_node in the child list of the parent;
      for (std::deque<DomainNameNode *>::iterator iter = new_node->parent->children.begin();
           iter != new_node->parent->children.end(); ++iter) {
        if (*(iter) == node) {
          *(iter) = new_node;
        }
      }
      retval = new_node;
    } else {
      // Will not replace in the equal case
      // Unless this is the root node
      if (node->key == "" && node->order == 0x7fffffff) {
        node->key     = key;
        node->payload = payload;
        node->order   = order;
        retval        = node;
      }
    }
  }
  TSMutexUnlock(this->tree_mutex);

  return retval;
}
<|endoftext|>


<commit_before>//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
//
// spdlog usage example
//
//
#include "spdlog/spdlog.h"

#include <iostream>
#include <memory>

void async_example();
void syslog_example();
void user_defined_example();
void err_handler_example();

namespace spd = spdlog;
int main(int, char*[])
{
    try
    {
        // Multithreaded color console
        auto console = spd::stdout_logger_mt("console", true);
        console->info("Welcome to spdlog!");
        console->error("An info message example {}..", 1);

        // Formatting examples
        console->warn("Easy padding in numbers like {:08d}", 12);
        console->critical("Support for int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
        console->info("Support for floats {:03.2f}", 1.23456);
        console->info("Positional args are {1} {0}..", "too", "supported");

        console->info("{:<30}", "left aligned");
        console->info("{:>30}", "right aligned");
        console->info("{:^30}", "centered");

        spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");

        // Runtime log levels
        spd::set_level(spd::level::info); //Set global log level to info
        console->debug("This message shold not be displayed!");
        console->set_level(spd::level::debug); // Set specific logger's log level
        console->debug("This message shold be displayed..");

        // Create basic file logger (not rotated)
        auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt");
        my_logger->info("Some log message");

        // Create a file rotating logger with 5mb size max and 3 rotated files
        auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile", 1048576 * 5, 3);
        for (int i = 0; i < 10; ++i)
            rotating_logger->info("{} * {} equals {:>10}", i, i, i*i);

        // Create a daily logger - a new file is created every day on 2:30am
        auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily", 2, 30);
        daily_logger->info(123.44);

        // Customize msg format for all messages
        spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
        rotating_logger->info("This is another message with custom format");

        // Compile time debug or trace macros.
        // Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON
        SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23);
        SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);

        // Asynchronous logging is very fast..
        // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
        async_example();

        // syslog example. linux/osx only
        syslog_example();

        // Log user-defined types example
        user_defined_example();

        // Change default log error handler
        err_handler_example();

        // Apply a function on all registered loggers
        spd::apply_all([&](std::shared_ptr<spdlog::logger> l)
        {
            l->info("End of example.");
        });

        // Release and close all loggers
        spdlog::drop_all();
    }
    // Exceptions will only be thrown upon failed logger or sink construction (not during logging)
    catch (const spd::spdlog_ex& ex)
    {
        std::cout << "Log init failed: " << ex.what() << std::endl;
        return 1;
    }
}

void async_example()
{
    size_t q_size = 4096; //queue size must be power of 2
    spdlog::set_async_mode(q_size);
    auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt");
    for (int i = 0; i < 100; ++i)
        async_file->info("Async message #{}", i);
}

//syslog example (linux/osx/freebsd)
void syslog_example()
{
#ifdef SPDLOG_ENABLE_SYSLOG
    std::string ident = "spdlog-example";
    auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID);
    syslog_logger->warn("This is warning that will end up in syslog.");
#endif
}

// user defined types logging by implementing operator<<
struct my_type
{
    int i;
    template<typename OStream>
    friend OStream& operator<<(OStream& os, const my_type &c)
    {
        return os << "[my_type i="<<c.i << "]";
    }
};

#include <spdlog/fmt/ostr.h> // must be included
void user_defined_example()
{
    spd::get("console")->info("user defined type: {}", my_type { 14 });
}

//
//custom error handler
//
void err_handler_example()
{
    //can be set globaly or per logger(logger->set_error_handler(..))
    spdlog::set_error_handler([](const std::string& msg)
    {
        std::cerr << "my err handler: " << msg << std::endl;
    });
    spd::get("console")->info("some invalid message to trigger an error {}{}{}{}", 3);
}

<commit_msg>fix typo in example<commit_after>//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
//
// spdlog usage example
//
//
#include "spdlog/spdlog.h"

#include <iostream>
#include <memory>

void async_example();
void syslog_example();
void user_defined_example();
void err_handler_example();

namespace spd = spdlog;
int main(int, char*[])
{
    try
    {
        // Multithreaded color console
        auto console = spd::stdout_logger_mt("console", true);
        console->info("Welcome to spdlog!");
        console->error("An error message example {}..", 1);

        // Formatting examples
        console->warn("Easy padding in numbers like {:08d}", 12);
        console->critical("Support for int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
        console->info("Support for floats {:03.2f}", 1.23456);
        console->info("Positional args are {1} {0}..", "too", "supported");

        console->info("{:<30}", "left aligned");
        console->info("{:>30}", "right aligned");
        console->info("{:^30}", "centered");

        spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");

        // Runtime log levels
        spd::set_level(spd::level::info); //Set global log level to info
        console->debug("This message shold not be displayed!");
        console->set_level(spd::level::debug); // Set specific logger's log level
        console->debug("This message shold be displayed..");

        // Create basic file logger (not rotated)
        auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt");
        my_logger->info("Some log message");

        // Create a file rotating logger with 5mb size max and 3 rotated files
        auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile", 1048576 * 5, 3);
        for (int i = 0; i < 10; ++i)
            rotating_logger->info("{} * {} equals {:>10}", i, i, i*i);

        // Create a daily logger - a new file is created every day on 2:30am
        auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily", 2, 30);
        daily_logger->info(123.44);

        // Customize msg format for all messages
        spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
        rotating_logger->info("This is another message with custom format");

        // Compile time debug or trace macros.
        // Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON
        SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23);
        SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);

        // Asynchronous logging is very fast..
        // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
        async_example();

        // syslog example. linux/osx only
        syslog_example();

        // Log user-defined types example
        user_defined_example();

        // Change default log error handler
        err_handler_example();

        // Apply a function on all registered loggers
        spd::apply_all([&](std::shared_ptr<spdlog::logger> l)
        {
            l->info("End of example.");
        });

        // Release and close all loggers
        spdlog::drop_all();
    }
    // Exceptions will only be thrown upon failed logger or sink construction (not during logging)
    catch (const spd::spdlog_ex& ex)
    {
        std::cout << "Log init failed: " << ex.what() << std::endl;
        return 1;
    }
}

void async_example()
{
    size_t q_size = 4096; //queue size must be power of 2
    spdlog::set_async_mode(q_size);
    auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt");
    for (int i = 0; i < 100; ++i)
        async_file->info("Async message #{}", i);
}

//syslog example (linux/osx/freebsd)
void syslog_example()
{
#ifdef SPDLOG_ENABLE_SYSLOG
    std::string ident = "spdlog-example";
    auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID);
    syslog_logger->warn("This is warning that will end up in syslog.");
#endif
}

// user defined types logging by implementing operator<<
struct my_type
{
    int i;
    template<typename OStream>
    friend OStream& operator<<(OStream& os, const my_type &c)
    {
        return os << "[my_type i="<<c.i << "]";
    }
};

#include <spdlog/fmt/ostr.h> // must be included
void user_defined_example()
{
    spd::get("console")->info("user defined type: {}", my_type { 14 });
}

//
//custom error handler
//
void err_handler_example()
{
    //can be set globaly or per logger(logger->set_error_handler(..))
    spdlog::set_error_handler([](const std::string& msg)
    {
        std::cerr << "my err handler: " << msg << std::endl;
    });
    spd::get("console")->info("some invalid message to trigger an error {}{}{}{}", 3);
}

<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** V4l2Device.cpp
**
** -------------------------------------------------------------------------*/

#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>

// libv4l2
#include <linux/videodev2.h>

#include "logger.h"

#include "V4l2Device.h"

// -----------------------------------------
//    V4L2Device
// -----------------------------------------
V4l2Device::V4l2Device(const V4L2DeviceParameters&  params, v4l2_buf_type deviceType) : m_params(params), m_fd(-1), m_deviceType(deviceType), m_bufferSize(0), m_format(0)
{
}

V4l2Device::~V4l2Device()
{
	this->close();
}

void V4l2Device::close()
{
	if (m_fd != -1)
		::close(m_fd);

	m_fd = -1;
}

// query current format
void V4l2Device::queryFormat()
{
	struct v4l2_format     fmt;
	memset(&fmt,0,sizeof(fmt));
	fmt.type  = m_deviceType;
	if (0 == ioctl(m_fd,VIDIOC_G_FMT,&fmt))
	{
		m_format     = fmt.fmt.pix.pixelformat;
		m_width      = fmt.fmt.pix.width;
		m_height     = fmt.fmt.pix.height;
		m_bufferSize = fmt.fmt.pix.sizeimage;
	}
}

// intialize the V4L2 connection
bool V4l2Device::init(unsigned int mandatoryCapabilities)
{
        struct stat sb;
        if ( (stat(m_params.m_devName.c_str(), &sb)==0) && ((sb.st_mode & S_IFMT) == S_IFCHR) )
        {
		if (initdevice(m_params.m_devName.c_str(), mandatoryCapabilities) == -1)
		{
			LOG(ERROR) << "Cannot init device:" << m_params.m_devName;
		}
	}
	else
	{
                // open a normal file
                m_fd = open(m_params.m_devName.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
	}
	return (m_fd!=-1);
}

// intialize the V4L2 device
int V4l2Device::initdevice(const char *dev_name, unsigned int mandatoryCapabilities)
{
	m_fd = open(dev_name,  O_RDWR | O_NONBLOCK);
	if (m_fd < 0)
	{
		LOG(ERROR) << "Cannot open device:" << m_params.m_devName << " " << strerror(errno);
		this->close();
		return -1;
	}
	if (checkCapabilities(m_fd,mandatoryCapabilities) !=0)
	{
		this->close();
		return -1;
	}
	if (configureFormat(m_fd) !=0)
	{
		this->close();
		return -1;
	}
	if (configureParam(m_fd) !=0)
	{
		this->close();
		return -1;
	}

	return m_fd;
}

// check needed V4L2 capabilities
int V4l2Device::checkCapabilities(int fd, unsigned int mandatoryCapabilities)
{
	struct v4l2_capability cap;
	memset(&(cap), 0, sizeof(cap));
	if (-1 == ioctl(fd, VIDIOC_QUERYCAP, &cap))
	{
		LOG(ERROR) << "Cannot get capabilities for device:" << m_params.m_devName << " " << strerror(errno);
		return -1;
	}
	LOG(NOTICE) << "driver:" << cap.driver << " capabilities:" << std::hex << cap.capabilities <<  " mandatory:" << mandatoryCapabilities << std::dec;

	if ((cap.capabilities & V4L2_CAP_VIDEO_OUTPUT))  LOG(NOTICE) << m_params.m_devName << " support output";
	if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) LOG(NOTICE) << m_params.m_devName << " support capture";

	if ((cap.capabilities & V4L2_CAP_READWRITE))     LOG(NOTICE) << m_params.m_devName << " support read/write";
	if ((cap.capabilities & V4L2_CAP_STREAMING))     LOG(NOTICE) << m_params.m_devName << " support streaming";

	if ((cap.capabilities & V4L2_CAP_TIMEPERFRAME))  LOG(NOTICE) << m_params.m_devName << " support timeperframe";

	if ( (cap.capabilities & mandatoryCapabilities) != mandatoryCapabilities )
	{
		LOG(ERROR) << "Mandatory capability not available for device:" << m_params.m_devName;
		return -1;
	}

	return 0;
}

std::string fourcc(unsigned int format)
{
	char formatArray[] = { (char)(format&0xff), (char)((format>>8)&0xff), (char)((format>>16)&0xff), (char)((format>>24)&0xff), 0 };
	return std::string(formatArray, strlen(formatArray));
}

// configure capture format
int V4l2Device::configureFormat(int fd)
{

	if (m_params.m_formatList.size()==0)
	{
		this->queryFormat();
		m_params.m_format = m_format;
		m_params.m_width  = m_width;
		m_params.m_height = m_height;
	}

	for (unsigned int format : m_params.m_formatList) {
		if (this->configureFormat(fd, format)==0) {
			return 0;
		}
	}
	return -1;
}

// configure capture format
int V4l2Device::configureFormat(int fd, unsigned int format)
{
	struct v4l2_format   fmt;
	memset(&(fmt), 0, sizeof(fmt));
	fmt.type                = m_deviceType;
	fmt.fmt.pix.width       = m_params.m_width;
	fmt.fmt.pix.height      = m_params.m_height;
	fmt.fmt.pix.pixelformat = format;
	fmt.fmt.pix.field       = V4L2_FIELD_ANY;

	if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)
	{
		LOG(ERROR) << "Cannot set format for device:" << m_params.m_devName << " " << strerror(errno);
		return -1;
	}
	if (fmt.fmt.pix.pixelformat != m_params.m_format)
	{
		LOG(ERROR) << "Cannot set pixelformat to:" << fourcc(m_params.m_format) << " format is:" << fourcc(fmt.fmt.pix.pixelformat);
		return -1;
	}
	if ((fmt.fmt.pix.width != m_params.m_width) || (fmt.fmt.pix.height != m_params.m_height))
	{
		LOG(WARN) << "Cannot set size width:" << fmt.fmt.pix.width << " height:" << fmt.fmt.pix.height;
	}

	m_format     = fmt.fmt.pix.pixelformat;
	m_width      = fmt.fmt.pix.width;
	m_height     = fmt.fmt.pix.height;
	m_bufferSize = fmt.fmt.pix.sizeimage;

	LOG(NOTICE) << m_params.m_devName << ":" << fourcc(m_format) << " size:" << m_params.m_width << "x" << m_params.m_height << " bufferSize:" << m_bufferSize;

	return 0;
}

// configure capture FPS
int V4l2Device::configureParam(int fd)
{
	if (m_params.m_fps!=0)
	{
		struct v4l2_streamparm   param;
		memset(&(param), 0, sizeof(param));
		param.type = m_deviceType;
		param.parm.capture.timeperframe.numerator = 1;
		param.parm.capture.timeperframe.denominator = m_params.m_fps;

		if (ioctl(fd, VIDIOC_S_PARM, &param) == -1)
		{
			LOG(WARN) << "Cannot set param for device:" << m_params.m_devName << " " << strerror(errno);
		}

		LOG(NOTICE) << "fps:" << param.parm.capture.timeperframe.numerator << "/" << param.parm.capture.timeperframe.denominator;
		LOG(NOTICE) << "nbBuffer:" << param.parm.capture.readbuffers;
	}

	return 0;
}

<commit_msg>allow to give a list of format<commit_after>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** V4l2Device.cpp
**
** -------------------------------------------------------------------------*/

#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>

// libv4l2
#include <linux/videodev2.h>

#include "logger.h"

#include "V4l2Device.h"

// -----------------------------------------
//    V4L2Device
// -----------------------------------------
V4l2Device::V4l2Device(const V4L2DeviceParameters&  params, v4l2_buf_type deviceType) : m_params(params), m_fd(-1), m_deviceType(deviceType), m_bufferSize(0), m_format(0)
{
}

V4l2Device::~V4l2Device()
{
	this->close();
}

void V4l2Device::close()
{
	if (m_fd != -1)
		::close(m_fd);

	m_fd = -1;
}

// query current format
void V4l2Device::queryFormat()
{
	struct v4l2_format     fmt;
	memset(&fmt,0,sizeof(fmt));
	fmt.type  = m_deviceType;
	if (0 == ioctl(m_fd,VIDIOC_G_FMT,&fmt))
	{
		m_format     = fmt.fmt.pix.pixelformat;
		m_width      = fmt.fmt.pix.width;
		m_height     = fmt.fmt.pix.height;
		m_bufferSize = fmt.fmt.pix.sizeimage;
	}
}

// intialize the V4L2 connection
bool V4l2Device::init(unsigned int mandatoryCapabilities)
{
        struct stat sb;
        if ( (stat(m_params.m_devName.c_str(), &sb)==0) && ((sb.st_mode & S_IFMT) == S_IFCHR) )
        {
		if (initdevice(m_params.m_devName.c_str(), mandatoryCapabilities) == -1)
		{
			LOG(ERROR) << "Cannot init device:" << m_params.m_devName;
		}
	}
	else
	{
                // open a normal file
                m_fd = open(m_params.m_devName.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
	}
	return (m_fd!=-1);
}

// intialize the V4L2 device
int V4l2Device::initdevice(const char *dev_name, unsigned int mandatoryCapabilities)
{
	m_fd = open(dev_name,  O_RDWR | O_NONBLOCK);
	if (m_fd < 0)
	{
		LOG(ERROR) << "Cannot open device:" << m_params.m_devName << " " << strerror(errno);
		this->close();
		return -1;
	}
	if (checkCapabilities(m_fd,mandatoryCapabilities) !=0)
	{
		this->close();
		return -1;
	}
	if (configureFormat(m_fd) !=0)
	{
		this->close();
		return -1;
	}
	if (configureParam(m_fd) !=0)
	{
		this->close();
		return -1;
	}

	return m_fd;
}

// check needed V4L2 capabilities
int V4l2Device::checkCapabilities(int fd, unsigned int mandatoryCapabilities)
{
	struct v4l2_capability cap;
	memset(&(cap), 0, sizeof(cap));
	if (-1 == ioctl(fd, VIDIOC_QUERYCAP, &cap))
	{
		LOG(ERROR) << "Cannot get capabilities for device:" << m_params.m_devName << " " << strerror(errno);
		return -1;
	}
	LOG(NOTICE) << "driver:" << cap.driver << " capabilities:" << std::hex << cap.capabilities <<  " mandatory:" << mandatoryCapabilities << std::dec;

	if ((cap.capabilities & V4L2_CAP_VIDEO_OUTPUT))  LOG(NOTICE) << m_params.m_devName << " support output";
	if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) LOG(NOTICE) << m_params.m_devName << " support capture";

	if ((cap.capabilities & V4L2_CAP_READWRITE))     LOG(NOTICE) << m_params.m_devName << " support read/write";
	if ((cap.capabilities & V4L2_CAP_STREAMING))     LOG(NOTICE) << m_params.m_devName << " support streaming";

	if ((cap.capabilities & V4L2_CAP_TIMEPERFRAME))  LOG(NOTICE) << m_params.m_devName << " support timeperframe";

	if ( (cap.capabilities & mandatoryCapabilities) != mandatoryCapabilities )
	{
		LOG(ERROR) << "Mandatory capability not available for device:" << m_params.m_devName;
		return -1;
	}

	return 0;
}

std::string fourcc(unsigned int format)
{
	char formatArray[] = { (char)(format&0xff), (char)((format>>8)&0xff), (char)((format>>16)&0xff), (char)((format>>24)&0xff), 0 };
	return std::string(formatArray, strlen(formatArray));
}

// configure capture format
int V4l2Device::configureFormat(int fd)
{

	if (m_params.m_formatList.size()==0)
	{
		this->queryFormat();
		m_params.m_format = m_format;
		m_params.m_width  = m_width;
		m_params.m_height = m_height;
	}

	for (unsigned int format : m_params.m_formatList) {
		if (this->configureFormat(fd, format)==0) {
			return 0;
		}
	}
	return -1;
}

// configure capture format
int V4l2Device::configureFormat(int fd, unsigned int format)
{
	struct v4l2_format   fmt;
	memset(&(fmt), 0, sizeof(fmt));
	fmt.type                = m_deviceType;
	fmt.fmt.pix.width       = m_params.m_width;
	fmt.fmt.pix.height      = m_params.m_height;
	fmt.fmt.pix.pixelformat = format;
	fmt.fmt.pix.field       = V4L2_FIELD_ANY;

	if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)
	{
		LOG(ERROR) << "Cannot set format for device:" << m_params.m_devName << " " << strerror(errno);
		return -1;
	}
	if (fmt.fmt.pix.pixelformat != format)
	{
		LOG(ERROR) << "Cannot set pixelformat to:" << fourcc(format) << " format is:" << fourcc(fmt.fmt.pix.pixelformat);
		return -1;
	}
	if ((fmt.fmt.pix.width != m_params.m_width) || (fmt.fmt.pix.height != m_params.m_height))
	{
		LOG(WARN) << "Cannot set size width:" << fmt.fmt.pix.width << " height:" << fmt.fmt.pix.height;
	}

	m_format     = fmt.fmt.pix.pixelformat;
	m_width      = fmt.fmt.pix.width;
	m_height     = fmt.fmt.pix.height;
	m_bufferSize = fmt.fmt.pix.sizeimage;

	LOG(NOTICE) << m_params.m_devName << ":" << fourcc(m_format) << " size:" << m_params.m_width << "x" << m_params.m_height << " bufferSize:" << m_bufferSize;

	return 0;
}

// configure capture FPS
int V4l2Device::configureParam(int fd)
{
	if (m_params.m_fps!=0)
	{
		struct v4l2_streamparm   param;
		memset(&(param), 0, sizeof(param));
		param.type = m_deviceType;
		param.parm.capture.timeperframe.numerator = 1;
		param.parm.capture.timeperframe.denominator = m_params.m_fps;

		if (ioctl(fd, VIDIOC_S_PARM, &param) == -1)
		{
			LOG(WARN) << "Cannot set param for device:" << m_params.m_devName << " " << strerror(errno);
		}

		LOG(NOTICE) << "fps:" << param.parm.capture.timeperframe.numerator << "/" << param.parm.capture.timeperframe.denominator;
		LOG(NOTICE) << "nbBuffer:" << param.parm.capture.readbuffers;
	}

	return 0;
}

<|endoftext|>


<commit_before>#include <algorithm>
#include <cstddef>
#include <string>

#include "js6chars.hpp"

static std::string small_number_repr(int value)
{
  return value == 0
      ? "+[]"
      : value == 1
        ? "++[[]][+[]]"
        : "++[" + number_repr(value -1) + "][+[]]";
}

static std::string number_repr_helper(int value)
{
  if (value < 10) return small_number_repr(value) + "+[]";
  return number_repr_helper(value/10) + "+(" + small_number_repr(value%10) + ")";
}

std::string number_repr(int value)
{
  if (value < 0)
  {
    return std::string("+(") + char_repr('-') + "+(" + number_repr_helper(-value) + "))";
  }
  return value < 10
      ? small_number_repr(value)
      : std::string("+(") + number_repr_helper(value) + ")";
}

namespace {
template <std::size_t N, class Gen> bool from_known_str(std::string& in, const char (&real_str)[N], Gen&& offuscated_gen, char value)
{
  char const* it = std::find(std::begin(real_str), std::end(real_str), value);
  if (it != std::end(real_str))
  {
    in = "(";
    in += offuscated_gen();
    in += "+[])";
    in += "[" + number_repr((int)(it - real_str)) + "]";
    return true;
  }
  return false;
}
}

std::string char_repr(char value)
{
  if (value >= '0' && value <= '9')
  {
    return number_repr(value-'0') + "+[]";
  }

  std::string out {};

  // undefined === [][0]
  if (from_known_str(out, "undefined", [](){ return std::string("[][+[]]"); }, value))
  {//
    return out;
  }

  // NaN === +("u")
  if (from_known_str(out, "NaN", [](){ return std::string("+(") + char_repr('u') + ")"; }, value))
  {
    return out;
  }

  // 1e+308 === 1e308
  if (from_known_str(out, "1e+308", [](){ return std::string("+(") + str_repr(std::string("1e308")) + ")"; }, value))
  {
    return out;
  }

  // function find() { [native code] } === []["find"]
  if (from_known_str(out, "function find()", [](){ return std::string("[][") + str_repr("find") + "]"; }, value))
  {
    return out;
  }

  // true === !![]
  if (from_known_str(out, "true", [](){ return std::string("!![]"); }, value))
  {
    return out;
  }

  // false === ![]
  if (from_known_str(out, "false", [](){ return std::string("![]"); }, value))
  {
    return out;
  }

  // [object Array Iterator] === []["entries"]()
  if (from_known_str(out, "[object Array Iterator]", [](){ return std::string("[][") + str_repr("entries") + "]()"; }, value))
  {
    return out;
  }

  // function Number() { [native code] } === (0).constructor === (0)["constructor"]
  if (from_known_str(out, "function Number()", [](){ return std::string("(+[])[") + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // function Array() { [native code] } === (0).constructor === (0)["constructor"]
  if (from_known_str(out, "function Array()", [](){ return std::string("[][") + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // function String() { [native code] } === (0).constructor === (0)["constructor"]
  if (from_known_str(out, "function String()", [](){ return std::string("([]+[])[") + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // function Function() { [native code] } === (0).constructor.constructor === (0)["constructor"]["constructor"]
  if (from_known_str(out, "function Function()", [](){ return std::string("[][") + str_repr("constructor") + "][" + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // function Boolean() { [native code] } === (0).constructor === (0)["constructor"]
  if (from_known_str(out, "function Boolean()", [](){ return std::string("(![])[") + str_repr("constructor") + "][" + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // "a" === 10["toString"](11)
  // "b" === 11["toString"](12)...
  if (value >= 'a' && value <= 'z')
  {
    return "(" + number_repr(10 + value -'a') + ")[" + str_repr("toString") + "](" + number_repr(11 + value -'a') + ")";
  }

  // "C" == window["atob"]("20N")[1]
  // "C" === Function("return atob(\"20N\")[1]")()
  if (value == 'C')
  {
    return run_command("return atob(" + str_repr("20N") + ")[1]");
  }

  // ([]+[])["constructor"]["fromCharCode"](\d+)
  return std::string("([]+[])[")
      + str_repr("constructor") + "]["
      + str_repr("fromCharCode") + "](" + number_repr((int)value) + ")";
}

std::string str_repr(const char* str)
{
  std::string out {};
  for (auto it = str ; *it ; ++it)
  {
    if (it != str)
    {
      out += '+';
    }
    out += '(';
    out += char_repr(*it);
    out += ')';
  }
  return out;
}
std::string str_repr(std::string const& in)
{
  return str_repr(in.c_str());
}

std::string run_command(const char* str)
{
  return std::string("[][") + str_repr("constructor") + "][" + str_repr("constructor") + "](" + str_repr(str) + ")()";
}
std::string run_command(std::string const& in)
{
  return run_command(in.c_str());
}

<commit_msg>Fix typos<commit_after>#include <algorithm>
#include <cstddef>
#include <string>

#include "js6chars.hpp"

static std::string small_number_repr(int value)
{
  return value == 0
      ? "+[]"
      : value == 1
        ? "++[[]][+[]]"
        : "++[" + number_repr(value -1) + "][+[]]";
}

static std::string number_repr_helper(int value)
{
  if (value < 10) return small_number_repr(value) + "+[]";
  return number_repr_helper(value/10) + "+(" + small_number_repr(value%10) + ")";
}

std::string number_repr(int value)
{
  if (value < 0)
  {
    return std::string("+(") + char_repr('-') + "+(" + number_repr_helper(-value) + "))";
  }
  return value < 10
      ? small_number_repr(value)
      : std::string("+(") + number_repr_helper(value) + ")";
}

namespace {
template <std::size_t N, class Gen> bool from_known_str(std::string& in, const char (&real_str)[N], Gen&& offuscated_gen, char value)
{
  char const* it = std::find(std::begin(real_str), std::end(real_str), value);
  if (it != std::end(real_str))
  {
    in = "(";
    in += offuscated_gen();
    in += "+[])";
    in += "[" + number_repr((int)(it - real_str)) + "]";
    return true;
  }
  return false;
}
}

std::string char_repr(char value)
{
  if (value >= '0' && value <= '9')
  {
    return number_repr(value-'0') + "+[]";
  }

  std::string out {};

  // undefined === [][0]
  if (from_known_str(out, "undefined", [](){ return std::string("[][+[]]"); }, value))
  {//
    return out;
  }

  // NaN === +("u")
  if (from_known_str(out, "NaN", [](){ return std::string("+(") + char_repr('u') + ")"; }, value))
  {
    return out;
  }

  // 1e+308 === 1e308
  if (from_known_str(out, "1e+308", [](){ return std::string("+(") + str_repr(std::string("1e308")) + ")"; }, value))
  {
    return out;
  }

  // function find() { [native code] } === []["find"]
  if (from_known_str(out, "function find()", [](){ return std::string("[][") + str_repr("find") + "]"; }, value))
  {
    return out;
  }

  // true === !![]
  if (from_known_str(out, "true", [](){ return std::string("!![]"); }, value))
  {
    return out;
  }

  // false === ![]
  if (from_known_str(out, "false", [](){ return std::string("![]"); }, value))
  {
    return out;
  }

  // [object Array Iterator] === []["entries"]()
  if (from_known_str(out, "[object Array Iterator]", [](){ return std::string("[][") + str_repr("entries") + "]()"; }, value))
  {
    return out;
  }

  // function Number() { [native code] } === (0).constructor === (0)["constructor"]
  if (from_known_str(out, "function Number()", [](){ return std::string("(+[])[") + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // function Array() { [native code] } === (0).constructor === (0)["constructor"]
  if (from_known_str(out, "function Array()", [](){ return std::string("[][") + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // function String() { [native code] } === (0).constructor === (0)["constructor"]
  if (from_known_str(out, "function String()", [](){ return std::string("([]+[])[") + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // function Function() { [native code] } === (0).constructor.constructor === (0)["constructor"]["constructor"]
  if (from_known_str(out, "function Function()", [](){ return std::string("[][") + str_repr("constructor") + "][" + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // function Boolean() { [native code] } === (0).constructor === (0)["constructor"]
  if (from_known_str(out, "function Boolean()", [](){ return std::string("(![])[") + str_repr("constructor") + "]"; }, value))
  {
    return out;
  }

  // "a" === 10["toString"](11)
  // "b" === 11["toString"](12)...
  if (value >= 'a' && value <= 'z')
  {
    return "(" + number_repr(10 + value -'a') + ")[" + str_repr("toString") + "](" + number_repr(11 + value -'a') + ")";
  }

  // "C" == window["atob"]("20N")[1]
  // "C" === Function("return atob(\"20N\")[1]")()
  if (value == 'C')
  {
    return run_command("return atob(" + str_repr("20N") + ")[1]");
  }

  // ([]+[])["constructor"]["fromCharCode"](\d+)
  return std::string("([]+[])[")
      + str_repr("constructor") + "]["
      + str_repr("fromCharCode") + "](" + number_repr((int)value) + ")";
}

std::string str_repr(const char* str)
{
  std::string out {};
  for (auto it = str ; *it ; ++it)
  {
    if (it != str)
    {
      out += '+';
    }
    out += '(';
    out += char_repr(*it);
    out += ')';
  }
  return out;
}
std::string str_repr(std::string const& in)
{
  return str_repr(in.c_str());
}

std::string run_command(const char* str)
{
  return std::string("[][") + str_repr("constructor") + "][" + str_repr("constructor") + "](" + str_repr(str) + ")()";
}
std::string run_command(std::string const& in)
{
  return run_command(in.c_str());
}

<|endoftext|>


<commit_before><commit_msg>Use assertions to ensure proper use of the osl command line arg API<commit_after><|endoftext|>


<commit_before><commit_msg>coverity#1209781 Resource leak<commit_after><|endoftext|>


<commit_before>/*
 *  Phusion Passenger - http://www.modrails.com/
 *  Copyright (C) 2008  Phusion
 *
 *  Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "Bucket.h"

static apr_status_t bucket_read(apr_bucket *a, const char **str, apr_size_t *len, apr_read_type_e block);

static const apr_bucket_type_t apr_bucket_type_passenger_pipe = {
	"PASSENGER_PIPE",
	5,
	apr_bucket_type_t::APR_BUCKET_DATA,
	apr_bucket_destroy_noop,
	bucket_read,
	apr_bucket_setaside_notimpl,
	apr_bucket_split_notimpl,
	apr_bucket_copy_notimpl
};

static apr_status_t
bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type_e block) {
	apr_file_t *pipe;
	char *buf;
	apr_status_t ret;
	apr_interval_time_t timeout;

	pipe = (apr_file_t *) bucket->data;
	if (block == APR_NONBLOCK_READ) {
		apr_file_pipe_timeout_get(pipe, &timeout);
		apr_file_pipe_timeout_set(pipe, 0);
	}

	*str = NULL;
	*len = APR_BUCKET_BUFF_SIZE;
	buf = (char *) apr_bucket_alloc(*len, bucket->list); // TODO: check for failure?

	ret = apr_file_read(pipe, buf, len);

	if (block == APR_NONBLOCK_READ) {
		apr_file_pipe_timeout_set(pipe, timeout);
	}

	if (ret != APR_SUCCESS && ret != APR_EOF) {
		// ... we might want to set an error flag here ...
		apr_bucket_free(buf);
		return ret;
	}
	/*
	 * If there's more to read we have to keep the rest of the pipe
	 * for later.
	 */
	if (*len > 0) {
		apr_bucket_heap *h;
		/* Change the current bucket to refer to what we read */
		bucket = apr_bucket_heap_make(bucket, buf, *len, apr_bucket_free);
		h = (apr_bucket_heap *) bucket->data;
		h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
		*str = buf;
		APR_BUCKET_INSERT_AFTER(bucket, passenger_bucket_create(pipe, bucket->list));
	} else {
		apr_bucket_free(buf);
		bucket = apr_bucket_immortal_make(bucket, "", 0);
		*str = (const char *) bucket->data;
		// if (rv != APR_EOF) {
		//     ... we might want to set an error flag here ...
		// }
	}
	return APR_SUCCESS;
}

apr_bucket *
passenger_bucket_make(apr_bucket *bucket, apr_file_t *pipe) {
	bucket->type   = &apr_bucket_type_passenger_pipe;
	bucket->length = (apr_size_t)(-1);
	bucket->start  = -1;
	bucket->data   = pipe;
	return bucket;
}

apr_bucket *
passenger_bucket_create(apr_file_t *pipe, apr_bucket_alloc_t *list) {
	apr_bucket *bucket;

	bucket = (apr_bucket *) apr_bucket_alloc(sizeof(*bucket), list);
	APR_BUCKET_INIT(bucket);
	bucket->free = apr_bucket_free;
	bucket->list = list;
	return passenger_bucket_make(bucket, pipe);
}

<commit_msg>Fix line terminators.<commit_after>/*
 *  Phusion Passenger - http://www.modrails.com/
 *  Copyright (C) 2008  Phusion
 *
 *  Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "Bucket.h"

static apr_status_t bucket_read(apr_bucket *a, const char **str, apr_size_t *len, apr_read_type_e block);

static const apr_bucket_type_t apr_bucket_type_passenger_pipe = {
	"PASSENGER_PIPE",
	5,
	apr_bucket_type_t::APR_BUCKET_DATA,
	apr_bucket_destroy_noop,
	bucket_read,
	apr_bucket_setaside_notimpl,
	apr_bucket_split_notimpl,
	apr_bucket_copy_notimpl
};

static apr_status_t
bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type_e block) {
	apr_file_t *pipe;
	char *buf;
	apr_status_t ret;
	apr_interval_time_t timeout;

	pipe = (apr_file_t *) bucket->data;
	if (block == APR_NONBLOCK_READ) {
		apr_file_pipe_timeout_get(pipe, &timeout);
		apr_file_pipe_timeout_set(pipe, 0);
	}

	*str = NULL;
	*len = APR_BUCKET_BUFF_SIZE;
	buf = (char *) apr_bucket_alloc(*len, bucket->list); // TODO: check for failure?

	ret = apr_file_read(pipe, buf, len);
	if (block == APR_NONBLOCK_READ) {
		apr_file_pipe_timeout_set(pipe, timeout);
	}

	if (ret != APR_SUCCESS && ret != APR_EOF) {
		// ... we might want to set an error flag here ...
		apr_bucket_free(buf);
		return ret;
	}
	/*
	 * If there's more to read we have to keep the rest of the pipe
	 * for later.
	 */
	if (*len > 0) {
		apr_bucket_heap *h;
		/* Change the current bucket to refer to what we read */
		bucket = apr_bucket_heap_make(bucket, buf, *len, apr_bucket_free);
		h = (apr_bucket_heap *) bucket->data;
		h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
		*str = buf;
		APR_BUCKET_INSERT_AFTER(bucket, passenger_bucket_create(pipe, bucket->list));
	} else {
		apr_bucket_free(buf);
		bucket = apr_bucket_immortal_make(bucket, "", 0);
		*str = (const char *) bucket->data;
		// if (rv != APR_EOF) {
		//     ... we might want to set an error flag here ...
		// }
	}
	return APR_SUCCESS;
}

apr_bucket *
passenger_bucket_make(apr_bucket *bucket, apr_file_t *pipe) {
	bucket->type   = &apr_bucket_type_passenger_pipe;
	bucket->length = (apr_size_t)(-1);
	bucket->start  = -1;
	bucket->data   = pipe;
	return bucket;
}

apr_bucket *
passenger_bucket_create(apr_file_t *pipe, apr_bucket_alloc_t *list) {
	apr_bucket *bucket;

	bucket = (apr_bucket *) apr_bucket_alloc(sizeof(*bucket), list);
	APR_BUCKET_INIT(bucket);
	bucket->free = apr_bucket_free;
	bucket->list = list;
	return passenger_bucket_make(bucket, pipe);
}

<|endoftext|>


<commit_before>#include "BoxSys.hpp"

#include "VseApp.hpp"
#include "BoxComp.hpp"

#include <sstream>
#include <stdint.h>

namespace vse
{

std::string BoxSys::generateOgreEntityName() {
    static uint32_t id = 0;

    std::stringstream ss;
    ss << "cube" << id;

    ++ id;
    return ss.str();

}

BoxSys::BoxSys() {
    requiredComponents.push_back(BoxComp::componentID);

    dynamicsWorld = VseApp::getSingleton().mDynamicsWorld;
    smgr = VseApp::getSingleton().mSmgr;
}

BoxSys::~BoxSys()
{
}

void BoxSys::onEntityExists(nres::Entity* entity) {
    BoxComp* comp = (BoxComp*) entity->getComponent(BoxComp::componentID);
    comp->boxNode = smgr->getRootSceneNode()->createChildSceneNode();
    comp->boxModel = smgr->createEntity(generateOgreEntityName(), "Cube.mesh");
    comp->boxNode->attachObject(comp->boxModel);

    btScalar mass = 1;
    btTransform trans;
    trans.setIdentity();
    trans.setOrigin(btVector3(4, 5, 4));
    comp->motionState = new BoxComp::RigidBodyMotionListener(trans, comp);
    btVector3 inertia(0, 0, 0);
    comp->mCollisionShape->calculateLocalInertia(mass, inertia);
    comp->rigidBody = new btRigidBody(mass, comp->motionState, comp->mCollisionShape, inertia);
    dynamicsWorld->addRigidBody(comp->rigidBody);

    trackedEntities.push_back(entity);
}
void BoxSys::onEntityDestroyed(nres::Entity* entity) {

}
void BoxSys::onEntityBroadcast(nres::Entity* entity, void* data) {

}
const std::vector<nres::ComponentID>& BoxSys::getRequiredComponents() {
    return requiredComponents;
}

void BoxSys::onTick(float tps) {
    for(std::vector<nres::Entity*>::iterator it = trackedEntities.begin(); it != trackedEntities.end(); ++ it) {
        nres::Entity* entity = *it;
        BoxComp* comp = (BoxComp*) entity->getComponent(BoxComp::componentID);

        comp->x += tps;

        if(comp->needsAttencion) {
            comp->boxNode->setPosition(comp->location.getX(), comp->location.getY(), comp->location.getZ());
            comp->boxNode->setOrientation(comp->rotation.getX(), comp->rotation.getY(), comp->rotation.getZ(), comp->rotation.getW());
        }

    }
}
}

<commit_msg>Fixed physics rotations<commit_after>#include "BoxSys.hpp"

#include "VseApp.hpp"
#include "BoxComp.hpp"

#include <sstream>
#include <stdint.h>

namespace vse
{

std::string BoxSys::generateOgreEntityName() {
    static uint32_t id = 0;

    std::stringstream ss;
    ss << "cube" << id;

    ++ id;
    return ss.str();

}

BoxSys::BoxSys() {
    requiredComponents.push_back(BoxComp::componentID);

    dynamicsWorld = VseApp::getSingleton().mDynamicsWorld;
    smgr = VseApp::getSingleton().mSmgr;
}

BoxSys::~BoxSys()
{
}

void BoxSys::onEntityExists(nres::Entity* entity) {
    BoxComp* comp = (BoxComp*) entity->getComponent(BoxComp::componentID);
    comp->boxNode = smgr->getRootSceneNode()->createChildSceneNode();
    comp->boxModel = smgr->createEntity(generateOgreEntityName(), "Cube.mesh");
    comp->boxNode->attachObject(comp->boxModel);

    btScalar mass = 1;
    btTransform trans;
    trans.setIdentity();
    trans.setOrigin(btVector3(4, 5, 4));
    comp->motionState = new BoxComp::RigidBodyMotionListener(trans, comp);
    btVector3 inertia(0, 0, 0);
    comp->mCollisionShape->calculateLocalInertia(mass, inertia);
    comp->rigidBody = new btRigidBody(mass, comp->motionState, comp->mCollisionShape, inertia);
    dynamicsWorld->addRigidBody(comp->rigidBody);

    trackedEntities.push_back(entity);
}
void BoxSys::onEntityDestroyed(nres::Entity* entity) {

}
void BoxSys::onEntityBroadcast(nres::Entity* entity, void* data) {

}
const std::vector<nres::ComponentID>& BoxSys::getRequiredComponents() {
    return requiredComponents;
}

void BoxSys::onTick(float tps) {
    for(std::vector<nres::Entity*>::iterator it = trackedEntities.begin(); it != trackedEntities.end(); ++ it) {
        nres::Entity* entity = *it;
        BoxComp* comp = (BoxComp*) entity->getComponent(BoxComp::componentID);

        comp->x += tps;

        if(comp->needsAttencion) {
            comp->boxNode->setPosition(comp->location.getX(), comp->location.getY(), comp->location.getZ());
            comp->boxNode->setOrientation(comp->rotation.getW(), comp->rotation.getX(), comp->rotation.getY(), comp->rotation.getZ());

            needsAttencion = false;
        }

    }
}
}

<|endoftext|>


<commit_before>/*

Name: Velvet
Author: Alvy Piper (no contact email currently)
CSGO adaptation: aixxe <aixxe@skyenet.org>
Copyright: 2015
Usage: More complex than GreenTea and also SDKless. A simple internal cheat with bunnyhop and norecoil, written for CSPromod BETA 1.10b for fun.
Using content created by: Casual_Hacker ( http://www.unknowncheats.me/forum/member239231.html ), NanoCat, and Valve.

Any content creator that wants their work removed can contact me on UnknownCheats for now. ( http://www.unknowncheats.me/forum/members/334125.html )

Feel free to redistribute, modify, and share. Please give credit where it is due, though.

*/

#include "velvet.h"

using namespace velvet;

void inject() //TODO: Change this with init::finalize in DLLMain.
{
	init::finalize();
}

bool __stdcall entry(HINSTANCE inst, DWORD reason, LPVOID reserved)
{
	if (reason == 1)
	{
		DisableThreadLibraryCalls(inst);
		CreateThread(0, 0, (LPTHREAD_START_ROUTINE) inject, 0, 0, 0);
	}
	TerminateThread(inject, 0);
	return 1;
}
<commit_msg>Update contact info.<commit_after>/*

Name: Velvet
Author: Alvy Piper <alvycat@protonmail.com>
CSGO adaptation: aixxe <aixxe@skyenet.org>
Copyright: 2015
Usage: More complex than GreenTea and also SDKless. A simple internal cheat with bunnyhop and norecoil, written for CSPromod BETA 1.10b for fun.
Using content created by: Casual_Hacker ( http://www.unknowncheats.me/forum/member239231.html ), NanoCat, and Valve.

Any content creator that wants their work removed can contact me on UnknownCheats for now. ( http://www.unknowncheats.me/forum/members/334125.html )

Feel free to redistribute, modify, and share. Please give credit where it is due, though.

*/

#include "velvet.h"

using namespace velvet;

void inject() //TODO: Change this with init::finalize in DLLMain.
{
	init::finalize();
}

bool __stdcall entry(HINSTANCE inst, DWORD reason, LPVOID reserved)
{
	if (reason == 1)
	{
		DisableThreadLibraryCalls(inst);
		CreateThread(0, 0, (LPTHREAD_START_ROUTINE) inject, 0, 0, 0);
	}
	TerminateThread(inject, 0);
	return 1;
}
<|endoftext|>


<commit_before>/**
 * Clever programming language
 * Copyright (c) 2011 Clever Team
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include "compiler/compiler.h"
#include "compiler/typechecker.h"

namespace clever { namespace ast {

/**
 * Performs a type compatible checking
 */
bool TypeChecker::checkCompatibleTypes(const Value* const lhs, const Value* const rhs) throw() {
	/**
	 * Constants with different type cannot performs operation
	 */

	if (lhs->isPrimitive() && rhs->isPrimitive()
		&& lhs->getTypePtr() != CLEVER_TYPE("String")
		&& rhs->getTypePtr()  != CLEVER_TYPE("String")) {
		return true;
	}
	else if (lhs->getTypePtr() == CLEVER_TYPE("String")
		&& rhs->getTypePtr() == CLEVER_TYPE("String")) {
		return true;
	}

	/**
	 * @TODO: check if a class is base of another
	 * if (lhs->isPrimitive() && rhs->isPrimitive() && !lhs->hasSameType(rhs))
	 */
	return lhs->hasSameType(rhs);
}

/**
 * Returns the type resulting of a binary expression of two compatible types
 */
const Type* TypeChecker::checkExprType(const Value* const lhs, const Value* const rhs) throw() {
	if (lhs->isPrimitive() && rhs->isPrimitive()
		&& !lhs->isString() && !rhs->isString()) {

		if (lhs->getTypePtr() == CLEVER_TYPE("Double")
			|| rhs->getTypePtr() == CLEVER_TYPE("Double")) {
			return CLEVER_TYPE("Double");
		}

		if (lhs->getTypePtr() == CLEVER_TYPE("Int")
			|| rhs->getTypePtr() == CLEVER_TYPE("Int")) {
			return CLEVER_TYPE("Int");
		}

		return CLEVER_TYPE("Bool");
	}

	if (lhs->getTypePtr() == CLEVER_TYPE("String")
		&& rhs->getTypePtr() == CLEVER_TYPE("String")) {
		return CLEVER_TYPE("String");
	}

	/* TODO: check for non-primitive types */
	return lhs->getTypePtr();
}

/**
 * Checks the function return type
 */
void TypeChecker::checkFunctionReturn(const Function* func, const Value* value, const Type* rtype, const location& loc) throw() {
	/**
	 * When the rtype is NULL, the return is expected to be Void
	 * When value is NULL, the return statement is empty
	 */
	if (value && rtype == NULL) {
		Compiler::errorf(loc, "Function `%S' cannot return value, it was declared as Void!", &func->getName());
	} else if (value == NULL && rtype) {
		Compiler::errorf(loc, "Function `%S' must return a value of type %s!", &func->getName(), rtype->getName());
	} else if (value && rtype) {
		const Type* vtype = value->getTypePtr();

		if (vtype != rtype) {
			Compiler::errorf(loc, "Function `%S' expects %s value as return, not %s value",
				&func->getName(), rtype->getName(), vtype->getName());
		}
	}
}

/**
 * Checks the number of arguments supplied to the function on call
 */
void TypeChecker::checkFunctionArgs(const Function* func, int num_args, const location& loc) throw() {
	int expected_args = func->getNumArgs();

	if (expected_args != -1 && num_args != expected_args) {
		Compiler::errorf(loc, "Function `%S' expects %l argument%s, %l supplied",
			&func->getName(), expected_args, (expected_args > 1 ? "s" : ""), num_args);
	}
}

/**
 * Creates a vector with the current value from a Value* pointers
 */
ValueVector* TypeChecker::functionArgs(ArgumentList* args) throw() {
	ValueVector* values = new ValueVector();
	const NodeList& nodes = args->getNodes();
	NodeList::const_iterator it = nodes.begin(), end = nodes.end();

	values->reserve(nodes.size());

	while (it != end) {
		Value* value;

		(*it)->accept(*this);

		value = (*it)->getValue();
		value->addRef();

		values->push_back(value);
		++it;
	}

	return values;
}

AST_VISITOR(TypeChecker, Identifier) {
	Value* ident = g_symtable.getValue(expr->getName());

	if (ident == NULL) {
		Compiler::errorf(expr->getLocation(), "Variable `%s' not found!", expr->getName());
	}

	/**
	 * Associate the Value* of the symbol to the identifier
	 */

	expr->setValue(ident);
	ident->addRef();
}

AST_VISITOR(TypeChecker, BinaryExpr) {
}

AST_VISITOR(TypeChecker, VariableDecl) {
	Identifier* variable = expr->getVariable();
	Value* var = new Value();
	const Type* type = g_symtable.getType(expr->getType()->getName());

	/**
	 * Check if the type wasn't declarated previously
	 */
	if (type == NULL) {
		Compiler::errorf(expr->getLocation(), "`%s' does not name a type",
			expr->getType()->getName());
	}

	/**
	 * Check if there is already a variable with same name in the current scope
	 */
	if (g_symtable.getValue(variable->getName(), false) != NULL) {
		Compiler::errorf(expr->getLocation(),
			"Already exists a variable named `%S' in the current scope!",
			variable->getName());
	}

	variable->setValue(var);

	var->setName(variable->getName());
	var->setTypePtr(type);

	var->addRef();

	g_symtable.push(var);
}

AST_VISITOR(TypeChecker, PreIncrement) {
	Identifier* ident = expr->getExpr();

	expr->setValue(g_symtable.getValue(ident->getName()));
}

AST_VISITOR(TypeChecker, PosIncrement) {
	Identifier* ident = expr->getExpr();

	expr->setValue(g_symtable.getValue(ident->getName()));
}

AST_VISITOR(TypeChecker, PreDecrement) {
	Identifier* ident = expr->getExpr();

	expr->setValue(g_symtable.getValue(ident->getName()));
}

AST_VISITOR(TypeChecker, PosDecrement) {
	Identifier* ident = expr->getExpr();

	expr->setValue(g_symtable.getValue(ident->getName()));
}

AST_VISITOR(TypeChecker, IfExpr) {
}

AST_VISITOR(TypeChecker, BlockNode) {
	NodeList& nodes = expr->getNodes();
	NodeList::const_iterator it = nodes.begin(), end = nodes.end();

	/**
	 * Create a new scope
	 */
	g_symtable.beginScope();

	/**
	 * Iterates statements inside the block
	 */
	while (it != end) {
		(*it)->accept(*this);
		++it;
	}

	/**
	 * Pops the scope
	 */
	g_symtable.endScope();
}

AST_VISITOR(TypeChecker, WhileExpr) {
}

AST_VISITOR(TypeChecker, ForExpr) {
}

AST_VISITOR(TypeChecker, LogicExpr) {
}

AST_VISITOR(TypeChecker, BreakNode) {
}

AST_VISITOR(TypeChecker, FunctionCall) {
	const CString* const name = expr->getFuncName();
	Value* fvalue = g_symtable.getValue(name);
	const Function* func;
	ASTNode* args = expr->getArgs();
	Value* arg_values = NULL;
	int num_args = args ? args->getNodes().size() : 0;

	if (fvalue == NULL) {
		Compiler::errorf(expr->getLocation(), "Function `%S' does not exists!", name);
	}

	func = static_cast<CallableValue*>(fvalue)->getFunction();

	checkFunctionArgs(func, num_args, expr->getLocation());

	/**
	 * Set the return type
	 */
	//expr->getValue()->setTypePtr(func->getReturn());

	if (num_args) {
		arg_values = new Value;
		arg_values->setType(Value::VECTOR);
		arg_values->setVector(functionArgs(static_cast<ArgumentList*>(args)));

		if (func->isUserDefined()) {
			Value* vars = const_cast<Function*>(func)->getVars();
			vars->addRef();
		}
		arg_values->addRef();
		expr->setArgsValue(arg_values);
	}

	expr->setFuncValue(static_cast<CallableValue*>(fvalue));
	fvalue->addRef();
}

AST_VISITOR(TypeChecker, MethodCall) {
}

AST_VISITOR(TypeChecker, AssignExpr) {
}

AST_VISITOR(TypeChecker, ImportStmt) {
	const CString* const package = expr->getPackageName();
	const CString* const module = expr->getModuleName();

	if (module) {
		/**
		 * Importing an specific module
		 * e.g. import std.io;
		 */
		if (isInteractive() && g_symtable.getScope().getLevel() == 1) {
			Compiler::import(g_symtable.getScope(0), package, module);
		} else {
			Compiler::import(g_symtable.getScope(), package, module);
		}
	} else {
		/**
		 * Importing an entire package
		 * e.g. import std;
		 */
		if (isInteractive() && g_symtable.getScope().getLevel() == 1) {
			Compiler::import(g_symtable.getScope(0), package);
		} else {
			Compiler::import(g_symtable.getScope(), package);
		}
	}
}

AST_VISITOR(TypeChecker, FuncDeclaration) {
}

AST_VISITOR(TypeChecker, ReturnStmt) {
}

AST_VISITOR(TypeChecker, ClassDeclaration) {
}

}} // clever::ast
<commit_msg>- Cosmetics<commit_after>/**
 * Clever programming language
 * Copyright (c) 2011 Clever Team
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include "compiler/compiler.h"
#include "compiler/typechecker.h"

namespace clever { namespace ast {

/**
 * Performs a type compatible checking
 */
bool TypeChecker::checkCompatibleTypes(const Value* const lhs, const Value* const rhs) throw() {
	/**
	 * Constants with different type cannot performs operation
	 */

	if (lhs->isPrimitive() && rhs->isPrimitive()
		&& lhs->getTypePtr() != CLEVER_TYPE("String")
		&& rhs->getTypePtr()  != CLEVER_TYPE("String")) {
		return true;
	}
	else if (lhs->getTypePtr() == CLEVER_TYPE("String")
		&& rhs->getTypePtr() == CLEVER_TYPE("String")) {
		return true;
	}

	/**
	 * @TODO: check if a class is base of another
	 * if (lhs->isPrimitive() && rhs->isPrimitive() && !lhs->hasSameType(rhs))
	 */
	return lhs->hasSameType(rhs);
}

/**
 * Returns the type resulting of a binary expression of two compatible types
 */
const Type* TypeChecker::checkExprType(const Value* const lhs, const Value* const rhs) throw() {
	if (lhs->isPrimitive() && rhs->isPrimitive()
		&& !lhs->isString() && !rhs->isString()) {

		if (lhs->getTypePtr() == CLEVER_TYPE("Double")
			|| rhs->getTypePtr() == CLEVER_TYPE("Double")) {
			return CLEVER_TYPE("Double");
		}

		if (lhs->getTypePtr() == CLEVER_TYPE("Int")
			|| rhs->getTypePtr() == CLEVER_TYPE("Int")) {
			return CLEVER_TYPE("Int");
		}

		return CLEVER_TYPE("Bool");
	}

	if (lhs->getTypePtr() == CLEVER_TYPE("String")
		&& rhs->getTypePtr() == CLEVER_TYPE("String")) {
		return CLEVER_TYPE("String");
	}

	/* TODO: check for non-primitive types */
	return lhs->getTypePtr();
}

/**
 * Checks the function return type
 */
void TypeChecker::checkFunctionReturn(const Function* func, const Value* value, const Type* rtype, const location& loc) throw() {
	/**
	 * When the rtype is NULL, the return is expected to be Void
	 * When value is NULL, the return statement is empty
	 */
	if (value && rtype == NULL) {
		Compiler::errorf(loc, "Function `%S' cannot return value, it was declared as Void!", &func->getName());
	} else if (value == NULL && rtype) {
		Compiler::errorf(loc, "Function `%S' must return a value of type %s!", &func->getName(), rtype->getName());
	} else if (value && rtype) {
		const Type* vtype = value->getTypePtr();

		if (vtype != rtype) {
			Compiler::errorf(loc, "Function `%S' expects %s value as return, not %s value",
				&func->getName(), rtype->getName(), vtype->getName());
		}
	}
}

/**
 * Checks the number of arguments supplied to the function on call
 */
void TypeChecker::checkFunctionArgs(const Function* func, int num_args, const location& loc) throw() {
	int expected_args = func->getNumArgs();

	if (expected_args != -1 && num_args != expected_args) {
		Compiler::errorf(loc, "Function `%S' expects %l argument%s, %l supplied",
			&func->getName(), expected_args, (expected_args > 1 ? "s" : ""), num_args);
	}
}

/**
 * Creates a vector with the current value from a Value* pointers
 */
ValueVector* TypeChecker::functionArgs(ArgumentList* args) throw() {
	ValueVector* values = new ValueVector();
	const NodeList& nodes = args->getNodes();
	NodeList::const_iterator it = nodes.begin(), end = nodes.end();

	values->reserve(nodes.size());

	while (it != end) {
		Value* value;

		(*it)->accept(*this);

		value = (*it)->getValue();
		value->addRef();

		values->push_back(value);
		++it;
	}

	return values;
}

AST_VISITOR(TypeChecker, Identifier) {
	Value* ident = g_symtable.getValue(expr->getName());

	if (ident == NULL) {
		Compiler::errorf(expr->getLocation(), "Variable `%s' not found!", expr->getName());
	}

	/**
	 * Associate the Value* of the symbol to the identifier
	 */
	expr->setValue(ident);
	ident->addRef();
}

AST_VISITOR(TypeChecker, BinaryExpr) {
}

AST_VISITOR(TypeChecker, VariableDecl) {
	Identifier* variable = expr->getVariable();
	Value* var = new Value();
	const Type* type = g_symtable.getType(expr->getType()->getName());

	/**
	 * Check if the type wasn't declarated previously
	 */
	if (type == NULL) {
		Compiler::errorf(expr->getLocation(), "`%s' does not name a type",
			expr->getType()->getName());
	}

	/**
	 * Check if there is already a variable with same name in the current scope
	 */
	if (g_symtable.getValue(variable->getName(), false) != NULL) {
		Compiler::errorf(expr->getLocation(),
			"Already exists a variable named `%S' in the current scope!",
			variable->getName());
	}

	variable->setValue(var);

	/**
	 * Registers a new variable
	 */
	var->setName(variable->getName());
	var->setTypePtr(type);
	var->addRef();

	g_symtable.push(var);
}

AST_VISITOR(TypeChecker, PreIncrement) {
	Identifier* ident = expr->getExpr();

	expr->setValue(g_symtable.getValue(ident->getName()));
}

AST_VISITOR(TypeChecker, PosIncrement) {
	Identifier* ident = expr->getExpr();

	expr->setValue(g_symtable.getValue(ident->getName()));
}

AST_VISITOR(TypeChecker, PreDecrement) {
	Identifier* ident = expr->getExpr();

	expr->setValue(g_symtable.getValue(ident->getName()));
}

AST_VISITOR(TypeChecker, PosDecrement) {
	Identifier* ident = expr->getExpr();

	expr->setValue(g_symtable.getValue(ident->getName()));
}

AST_VISITOR(TypeChecker, IfExpr) {
}

AST_VISITOR(TypeChecker, BlockNode) {
	NodeList& nodes = expr->getNodes();
	NodeList::const_iterator it = nodes.begin(), end = nodes.end();

	/**
	 * Create a new scope
	 */
	g_symtable.beginScope();

	/**
	 * Iterates statements inside the block
	 */
	while (it != end) {
		(*it)->accept(*this);
		++it;
	}

	/**
	 * Pops the scope
	 */
	g_symtable.endScope();
}

AST_VISITOR(TypeChecker, WhileExpr) {
}

AST_VISITOR(TypeChecker, ForExpr) {
}

AST_VISITOR(TypeChecker, LogicExpr) {
}

AST_VISITOR(TypeChecker, BreakNode) {
}

AST_VISITOR(TypeChecker, FunctionCall) {
	const CString* const name = expr->getFuncName();
	Value* fvalue = g_symtable.getValue(name);
	const Function* func;
	ASTNode* args = expr->getArgs();
	Value* arg_values = NULL;
	int num_args = args ? args->getNodes().size() : 0;

	if (fvalue == NULL) {
		Compiler::errorf(expr->getLocation(), "Function `%S' does not exists!", name);
	}

	func = static_cast<CallableValue*>(fvalue)->getFunction();

	checkFunctionArgs(func, num_args, expr->getLocation());

	/**
	 * Set the return type
	 */
	expr->getValue()->setTypePtr(func->getReturn());

	if (num_args) {
		arg_values = new Value;
		arg_values->setType(Value::VECTOR);
		arg_values->setVector(functionArgs(static_cast<ArgumentList*>(args)));

		if (func->isUserDefined()) {
			Value* vars = const_cast<Function*>(func)->getVars();
			vars->addRef();
		}
		arg_values->addRef();
		expr->setArgsValue(arg_values);
	}

	expr->setFuncValue(static_cast<CallableValue*>(fvalue));
	fvalue->addRef();
}

AST_VISITOR(TypeChecker, MethodCall) {
}

AST_VISITOR(TypeChecker, AssignExpr) {
}

AST_VISITOR(TypeChecker, ImportStmt) {
	const CString* const package = expr->getPackageName();
	const CString* const module = expr->getModuleName();

	if (module) {
		/**
		 * Importing an specific module
		 * e.g. import std.io;
		 */
		if (isInteractive() && g_symtable.getScope().getLevel() == 1) {
			Compiler::import(g_symtable.getScope(0), package, module);
		} else {
			Compiler::import(g_symtable.getScope(), package, module);
		}
	} else {
		/**
		 * Importing an entire package
		 * e.g. import std;
		 */
		if (isInteractive() && g_symtable.getScope().getLevel() == 1) {
			Compiler::import(g_symtable.getScope(0), package);
		} else {
			Compiler::import(g_symtable.getScope(), package);
		}
	}
}

AST_VISITOR(TypeChecker, FuncDeclaration) {
}

AST_VISITOR(TypeChecker, ReturnStmt) {
}

AST_VISITOR(TypeChecker, ClassDeclaration) {
}

}} // clever::ast
<|endoftext|>


<commit_before>// $Id: metis_partitioner.C,v 1.22 2005-09-30 20:14:12 benkirk Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ Includes   -----------------------------------

// Local Includes -----------------------------------
#include "libmesh_config.h"
#include "mesh_base.h"
#include "metis_partitioner.h"
#include "libmesh_logging.h"
#include "elem.h"

#ifdef HAVE_METIS
// MIPSPro 7.4.2 gets confused about these nested namespaces
# ifdef __sgi
#  include <cstdarg>
# endif
  namespace Metis {
    extern "C" {
#     include "metis.h"
    }
  }
#else
#  include "sfc_partitioner.h"
#endif

// ------------------------------------------------------------
// MetisPartitioner implementation
void MetisPartitioner::_do_partition (MeshBase& mesh,
				      const unsigned int n_pieces)
{
  assert (n_pieces > 0);

  // Check for an easy return
  if (n_pieces == 1)
    {
      this->single_partition (mesh);
      return;
    }

// What to do if the Metis library IS NOT present
#ifndef HAVE_METIS

  here();
  std::cerr << "ERROR: The library has been built without"    << std::endl
	    << "Metis support.  Using a space-filling curve"  << std::endl
	    << "partitioner instead!"                         << std::endl;

  SFCPartitioner sfcp;

  sfcp.partition (mesh, n_pieces);

// What to do if the Metis library IS present
#else

  START_LOG("partition()", "MetisPartitioner");

  const unsigned int n_active_elem = mesh.n_active_elem();
  const unsigned int n_elem        = mesh.n_elem();

  // build the graph
  // the forward_map maps each active element id
  // into a contiguous block of indices for Metis
  std::vector<unsigned int> forward_map (n_elem, libMesh::invalid_uint);

  std::vector<int> xadj;
  std::vector<int> adjncy;
  std::vector<int> options(5);
  std::vector<int> vwgt(n_active_elem);
  std::vector<int> part(n_active_elem);

  xadj.reserve(n_active_elem+1);

  int
    n = static_cast<int>(n_active_elem),  // number of "nodes" (elements)
                                          //   in the graph
    wgtflag = 2,                          // weights on vertices only,
                                          //   none on edges
    numflag = 0,                          // C-style 0-based numbering
    nparts  = static_cast<int>(n_pieces), // number of subdomains to create
    edgecut = 0;                          // the numbers of edges cut by the
                                          //   resulting partition

  // Set the options
  options[0] = 0; // use default options

  // Metis will only consider the active elements.
  // We need to map the active element ids into a
  // contiguous range.
  {

    MeshBase::element_iterator       elem_it  = mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = mesh.active_elements_end();

    unsigned int el_num = 0;

    for (; elem_it != elem_end; ++elem_it)
      {
	assert ((*elem_it)->id() < forward_map.size());

	forward_map[(*elem_it)->id()] = el_num++;
      }

    assert (el_num == n_active_elem);
   }

  // build the graph in CSR format.  Note that
  // the edges in the graph will correspond to
  // face neighbors
  {
    std::vector<const Elem*> neighbors_offspring;

    MeshBase::element_iterator       elem_it  = mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = mesh.active_elements_end();

    // This will be exact when there is no refinement and all the
    // elements are of the same type.
    adjncy.reserve (n_active_elem*(*elem_it)->n_neighbors());

    for (; elem_it != elem_end; ++elem_it)
      {
	const Elem* elem = *elem_it;

	assert (elem->id() < forward_map.size());
	assert (forward_map[elem->id()] != libMesh::invalid_uint);

	// maybe there is a better weight?
	// The weight is used to define what a balanced graph is
	vwgt[forward_map[elem->id()]] = elem->n_nodes();

	// The beginning of the adjacency array for this elem
	xadj.push_back(adjncy.size());

	// Loop over the element's neighbors.  An element
	// adjacency corresponds to a face neighbor
	for (unsigned int ms=0; ms<elem->n_neighbors(); ms++)
	  {
	    const Elem* neighbor = elem->neighbor(ms);

	    if (neighbor != NULL)
	      {
		// If the neighbor is active treat it
		// as a connection
		if (neighbor->active())
		  {
		    assert (neighbor->id() < forward_map.size());
		    assert (forward_map[neighbor->id()] != libMesh::invalid_uint);

		    adjncy.push_back (forward_map[neighbor->id()]);
		  }

#ifdef ENABLE_AMR

		// Otherwise we need to find all of the
		// neighbor's children that are connected to
		// us and add them
		else
		  {
		    // The side of the neighbor to which
		    // we are connected
		    const unsigned int ns =
		      neighbor->which_neighbor_am_i (elem);

		    // Get all the active children (& grandchildren, etc...)
		    // of the neighbor.
		    neighbor->active_family_tree (neighbors_offspring);

		    // Get all the neighbor's children that
		    // live on that side and are thus connected
		    // to us
		    for (unsigned int nc=0; nc<neighbors_offspring.size(); nc++)
		      {
			const Elem* child =
			  neighbors_offspring[nc];

			// This does not assume a level-1 mesh.
			// Note that since children have sides numbered
			// coincident with the parent then this is a sufficient test.
			if (child->neighbor(ns) == elem)
			  {
			    assert (child->active());
			    assert (child->id() < forward_map.size());
			    assert (forward_map[child->id()] != libMesh::invalid_uint);

			    adjncy.push_back (forward_map[child->id()]);
			  }
		      }
		  }

#endif /* ifdef ENABLE_AMR */

	      }
	  }
      }

    // The end of the adjacency array for the last elem
    xadj.push_back(adjncy.size());

  } // done building the graph

  // Select which type of partitioning to create

  // Use recursive if the number of partitions is less than or equal to 8
  if (n_pieces <= 8)
    Metis::METIS_PartGraphRecursive(&n, &xadj[0], &adjncy[0], &vwgt[0], NULL,
				    &wgtflag, &numflag, &nparts, &options[0],
				    &edgecut, &part[0]);

  // Otherwise  use kway
  else
    Metis::METIS_PartGraphKway(&n, &xadj[0], &adjncy[0], &vwgt[0], NULL,
			       &wgtflag, &numflag, &nparts, &options[0],
			       &edgecut, &part[0]);

  // Assign the returned processor ids.  The part array contains
  // the processor id for each active element, but in terms of
  // the contiguous indexing we defined above
  {

    MeshBase::element_iterator       elem_it  = mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = mesh.active_elements_end();

    for (; elem_it != elem_end; ++elem_it)
      {
	Elem* elem = *elem_it;

	assert (elem->id() < forward_map.size());
	assert (forward_map[elem->id()] != libMesh::invalid_uint);

	elem->processor_id() =
	  static_cast<short int>(part[forward_map[elem->id()]]);
      }
  }

  STOP_LOG("partition()", "MetisPartitioner");

#endif

}
<commit_msg>Hackish "fix" for the "partitioning one element" bug.<commit_after>// $Id: metis_partitioner.C,v 1.23 2006-08-11 21:47:22 roystgnr Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ Includes   -----------------------------------

// Local Includes -----------------------------------
#include "libmesh_config.h"
#include "mesh_base.h"
#include "metis_partitioner.h"
#include "libmesh_logging.h"
#include "elem.h"

#ifdef HAVE_METIS
// MIPSPro 7.4.2 gets confused about these nested namespaces
# ifdef __sgi
#  include <cstdarg>
# endif
  namespace Metis {
    extern "C" {
#     include "metis.h"
    }
  }
#else
#  include "sfc_partitioner.h"
#endif

// ------------------------------------------------------------
// MetisPartitioner implementation
void MetisPartitioner::_do_partition (MeshBase& mesh,
				      const unsigned int n_pieces)
{
  assert (n_pieces > 0);

  // Check for an easy return
  if (n_pieces == 1)
    {
      this->single_partition (mesh);
      return;
    }

// What to do if the Metis library IS NOT present
#ifndef HAVE_METIS

  here();
  std::cerr << "ERROR: The library has been built without"    << std::endl
	    << "Metis support.  Using a space-filling curve"  << std::endl
	    << "partitioner instead!"                         << std::endl;

  SFCPartitioner sfcp;

  sfcp.partition (mesh, n_pieces);

// What to do if the Metis library IS present
#else

  START_LOG("partition()", "MetisPartitioner");

  const unsigned int n_active_elem = mesh.n_active_elem();
  const unsigned int n_elem        = mesh.n_elem();

  // build the graph
  // the forward_map maps each active element id
  // into a contiguous block of indices for Metis
  std::vector<unsigned int> forward_map (n_elem, libMesh::invalid_uint);

  std::vector<int> xadj;
  std::vector<int> adjncy;
  std::vector<int> options(5);
  std::vector<int> vwgt(n_active_elem);
  std::vector<int> part(n_active_elem);

  xadj.reserve(n_active_elem+1);

  int
    n = static_cast<int>(n_active_elem),  // number of "nodes" (elements)
                                          //   in the graph
    wgtflag = 2,                          // weights on vertices only,
                                          //   none on edges
    numflag = 0,                          // C-style 0-based numbering
    nparts  = static_cast<int>(n_pieces), // number of subdomains to create
    edgecut = 0;                          // the numbers of edges cut by the
                                          //   resulting partition

  // Set the options
  options[0] = 0; // use default options

  // Metis will only consider the active elements.
  // We need to map the active element ids into a
  // contiguous range.
  {

    MeshBase::element_iterator       elem_it  = mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = mesh.active_elements_end();

    unsigned int el_num = 0;

    for (; elem_it != elem_end; ++elem_it)
      {
	assert ((*elem_it)->id() < forward_map.size());

	forward_map[(*elem_it)->id()] = el_num++;
      }

    assert (el_num == n_active_elem);
   }

  // build the graph in CSR format.  Note that
  // the edges in the graph will correspond to
  // face neighbors
  {
    std::vector<const Elem*> neighbors_offspring;

    MeshBase::element_iterator       elem_it  = mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = mesh.active_elements_end();

    // This will be exact when there is no refinement and all the
    // elements are of the same type.
    adjncy.reserve (n_active_elem*(*elem_it)->n_neighbors());

    for (; elem_it != elem_end; ++elem_it)
      {
	const Elem* elem = *elem_it;

	assert (elem->id() < forward_map.size());
	assert (forward_map[elem->id()] != libMesh::invalid_uint);

	// maybe there is a better weight?
	// The weight is used to define what a balanced graph is
	vwgt[forward_map[elem->id()]] = elem->n_nodes();

	// The beginning of the adjacency array for this elem
	xadj.push_back(adjncy.size());

	// Loop over the element's neighbors.  An element
	// adjacency corresponds to a face neighbor
	for (unsigned int ms=0; ms<elem->n_neighbors(); ms++)
	  {
	    const Elem* neighbor = elem->neighbor(ms);

	    if (neighbor != NULL)
	      {
		// If the neighbor is active treat it
		// as a connection
		if (neighbor->active())
		  {
		    assert (neighbor->id() < forward_map.size());
		    assert (forward_map[neighbor->id()] != libMesh::invalid_uint);

		    adjncy.push_back (forward_map[neighbor->id()]);
		  }

#ifdef ENABLE_AMR

		// Otherwise we need to find all of the
		// neighbor's children that are connected to
		// us and add them
		else
		  {
		    // The side of the neighbor to which
		    // we are connected
		    const unsigned int ns =
		      neighbor->which_neighbor_am_i (elem);

		    // Get all the active children (& grandchildren, etc...)
		    // of the neighbor.
		    neighbor->active_family_tree (neighbors_offspring);

		    // Get all the neighbor's children that
		    // live on that side and are thus connected
		    // to us
		    for (unsigned int nc=0; nc<neighbors_offspring.size(); nc++)
		      {
			const Elem* child =
			  neighbors_offspring[nc];

			// This does not assume a level-1 mesh.
			// Note that since children have sides numbered
			// coincident with the parent then this is a sufficient test.
			if (child->neighbor(ns) == elem)
			  {
			    assert (child->active());
			    assert (child->id() < forward_map.size());
			    assert (forward_map[child->id()] != libMesh::invalid_uint);

			    adjncy.push_back (forward_map[child->id()]);
			  }
		      }
		  }

#endif /* ifdef ENABLE_AMR */

	      }
	  }
      }

    // The end of the adjacency array for the last elem
    xadj.push_back(adjncy.size());

  } // done building the graph

if (adjncy.empty())
  adjncy.push_back(0);

  // Select which type of partitioning to create

  // Use recursive if the number of partitions is less than or equal to 8
  if (n_pieces <= 8)
    Metis::METIS_PartGraphRecursive(&n, &xadj[0], &adjncy[0], &vwgt[0], NULL,
				    &wgtflag, &numflag, &nparts, &options[0],
				    &edgecut, &part[0]);

  // Otherwise  use kway
  else
    Metis::METIS_PartGraphKway(&n, &xadj[0], &adjncy[0], &vwgt[0], NULL,
			       &wgtflag, &numflag, &nparts, &options[0],
			       &edgecut, &part[0]);

  // Assign the returned processor ids.  The part array contains
  // the processor id for each active element, but in terms of
  // the contiguous indexing we defined above
  {

    MeshBase::element_iterator       elem_it  = mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = mesh.active_elements_end();

    for (; elem_it != elem_end; ++elem_it)
      {
	Elem* elem = *elem_it;

	assert (elem->id() < forward_map.size());
	assert (forward_map[elem->id()] != libMesh::invalid_uint);

	elem->processor_id() =
	  static_cast<short int>(part[forward_map[elem->id()]]);
      }
  }

  STOP_LOG("partition()", "MetisPartitioner");

#endif

}
<|endoftext|>