<commit_before>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

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

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif

#include <prio.h>
#include <prinrval.h>

#include <vpr/Util/Assert.h>
#include <vpr/md/NSPR/IO/Socket/SocketDatagramImplNSPR.h>

// ============================================================================
// External global variables.
// ============================================================================
extern int errno;

namespace vpr {

// ============================================================================
// Public methods.
// ============================================================================

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
Status
SocketDatagramImplNSPR::recvfrom (void* msg, const size_t length,
                                  const int flags, InetAddr& from,
                                  ssize_t& bytes_read,
                                  const vpr::Interval timeout)
{
    Status retval;

    bytes_read = PR_RecvFrom(m_handle, msg, length, flags, from.getPRNetAddr(),
                             NSPR_getInterval(timeout) );

    if ( bytes_read == -1 ) {
        PRErrorCode err_code = PR_GetError();

        if ( err_code == PR_WOULD_BLOCK_ERROR ) {
            retval.setCode(Status::InProgress);
        }
        else if ( err_code == PR_IO_TIMEOUT_ERROR ) {
            retval.setCode(Status::Timeout);
        }
        else {
            NSPR_PrintError("SocketDatagramImplNSPR::recvfrom: Could not read from socket");
            retval.setCode(Status::Failure);
        }
    }

    return retval;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
Status
SocketDatagramImplNSPR::sendto (const void* msg, const size_t length,
                                const int flags, const InetAddr& to,
                                ssize_t& bytes_sent,
                                const vpr::Interval timeout)
{
    Status retval;

    bytes_sent = PR_SendTo(m_handle, msg, length, flags, to.getPRNetAddr(),
                           NSPR_getInterval(timeout));

    if ( bytes_sent == -1 ) {
        PRErrorCode err_code;

        if ( err_code == PR_WOULD_BLOCK_ERROR ) {
            retval.setCode(Status::InProgress);
        }
        else if ( err_code == PR_IO_TIMEOUT_ERROR ) {
            retval.setCode(Status::Timeout);
        }
        else {
            NSPR_PrintError("SocketDatagramImplNSPR::sendto: Could not send message");
            retval.setCode(Status::Failure);
        }
    }

    return retval;
}

} // End of vpr namespace
<commit_msg>Added a missing call to PR_GetError() in sendto().<commit_after>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

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

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif

#include <prio.h>
#include <prinrval.h>

#include <vpr/Util/Assert.h>
#include <vpr/md/NSPR/IO/Socket/SocketDatagramImplNSPR.h>

// ============================================================================
// External global variables.
// ============================================================================
extern int errno;

namespace vpr {

// ============================================================================
// Public methods.
// ============================================================================

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
Status
SocketDatagramImplNSPR::recvfrom (void* msg, const size_t length,
                                  const int flags, InetAddr& from,
                                  ssize_t& bytes_read,
                                  const vpr::Interval timeout)
{
    Status retval;

    bytes_read = PR_RecvFrom(m_handle, msg, length, flags, from.getPRNetAddr(),
                             NSPR_getInterval(timeout) );

    if ( bytes_read == -1 ) {
        PRErrorCode err_code = PR_GetError();

        if ( err_code == PR_WOULD_BLOCK_ERROR ) {
            retval.setCode(Status::InProgress);
        }
        else if ( err_code == PR_IO_TIMEOUT_ERROR ) {
            retval.setCode(Status::Timeout);
        }
        else {
            NSPR_PrintError("SocketDatagramImplNSPR::recvfrom: Could not read from socket");
            retval.setCode(Status::Failure);
        }
    }

    return retval;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
Status
SocketDatagramImplNSPR::sendto (const void* msg, const size_t length,
                                const int flags, const InetAddr& to,
                                ssize_t& bytes_sent,
                                const vpr::Interval timeout)
{
    Status retval;

    bytes_sent = PR_SendTo(m_handle, msg, length, flags, to.getPRNetAddr(),
                           NSPR_getInterval(timeout));

    if ( bytes_sent == -1 ) {
        PRErrorCode err_code = PR_GetError();

        if ( err_code == PR_WOULD_BLOCK_ERROR ) {
            retval.setCode(Status::InProgress);
        }
        else if ( err_code == PR_IO_TIMEOUT_ERROR ) {
            retval.setCode(Status::Timeout);
        }
        else {
            NSPR_PrintError("SocketDatagramImplNSPR::sendto: Could not send message");
            retval.setCode(Status::Failure);
        }
    }

    return retval;
}

} // End of vpr namespace
<|endoftext|>


<commit_before>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vpr/vprConfig.h>

#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>

#include <vpr/Util/Assert.h>
#include <vpr/Util/Debug.h>
#include <vpr/md/POSIX/IO/Socket/SocketDatagramImplBSD.h>

// ============================================================================
// External global variables.
// ============================================================================
extern int errno;

namespace vpr {

// ============================================================================
// Public methods.
// ============================================================================

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
Status
SocketDatagramImplBSD::recvfrom (void* msg, const vpr::Uint32 length,
                                 const int flags, InetAddr& from,
                                 vpr::Uint32& bytes_read,
                                 const vpr::Interval timeout)
{
    socklen_t fromlen;
    Status retval;

    retval = m_handle->isReadable(timeout);

    if ( retval.success() ) {
        ssize_t bytes;

        m_blocking_fixed = true;

        fromlen    = from.size();
        bytes = ::recvfrom(m_handle->m_fdesc, msg, length, flags,
                           (struct sockaddr*) &from.m_addr, &fromlen);

        if ( bytes_read == -1 ) {
            bytes_read = 0;

            if ( errno == EAGAIN && getNonBlocking() ) {
                retval.setCode(Status::WouldBlock);
            }
            else {
                fprintf(stderr,
                        "[vpr::SocketDatagramImplBSD] ERROR: Could not read from socket (%s:%hu): %s\n",
                        m_remote_addr.getAddressString().c_str(),
                        m_remote_addr.getPort(), strerror(errno));
                retval.setCode(Status::Failure);
            }
        }
        else {
            bytes_read = bytes;
        }
    }

    return retval;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
Status
SocketDatagramImplBSD::sendto (const void* msg, const vpr::Uint32 length,
                               const int flags, const InetAddr& to,
                               vpr::Uint32& bytes_sent,
                               const vpr::Interval timeout)
{
    Status retval;

    retval = m_handle->isWriteable(timeout);

    if ( retval.success() ) {
        ssize_t bytes;

        m_blocking_fixed = true;

        bytes = ::sendto(m_handle->m_fdesc, msg, length, flags,
                         (struct sockaddr*) &to.m_addr, to.size());

        if ( bytes == -1 ) {
            bytes_sent = 0;

            if ( errno == EAGAIN && getNonBlocking() ) {
                retval.setCode(Status::WouldBlock);
            }
            else {
                fprintf(stderr,
                        "[vpr::SocketDatagramImplBSD] ERROR: Could not send to %s:%hu on socket (%s:%hu): %s\n",
                        to.getAddressString().c_str(), to.getPort(),
                        m_remote_addr.getAddressString().c_str(),
                        m_remote_addr.getPort(), strerror(errno));
                retval.setCode(Status::Failure);
            }
        }
        else {
            bytes_sent = bytes;
        }
    }

    return retval;
}

}; // End of vpr namespace
<commit_msg>Fixed an error in recvfrom() where the wrong variable was being compared against -1 after the recvfrom(2) system call.<commit_after>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vpr/vprConfig.h>

#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>

#include <vpr/Util/Assert.h>
#include <vpr/Util/Debug.h>
#include <vpr/md/POSIX/IO/Socket/SocketDatagramImplBSD.h>

// ============================================================================
// External global variables.
// ============================================================================
extern int errno;

namespace vpr {

// ============================================================================
// Public methods.
// ============================================================================

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
Status
SocketDatagramImplBSD::recvfrom (void* msg, const vpr::Uint32 length,
                                 const int flags, InetAddr& from,
                                 vpr::Uint32& bytes_read,
                                 const vpr::Interval timeout)
{
    socklen_t fromlen;
    Status retval;

    retval = m_handle->isReadable(timeout);

    if ( retval.success() ) {
        ssize_t bytes;

        m_blocking_fixed = true;

        fromlen    = from.size();
        bytes = ::recvfrom(m_handle->m_fdesc, msg, length, flags,
                           (struct sockaddr*) &from.m_addr, &fromlen);

        if ( bytes == -1 ) {
            bytes_read = 0;

            if ( errno == EAGAIN && getNonBlocking() ) {
                retval.setCode(Status::WouldBlock);
            }
            else {
                fprintf(stderr,
                        "[vpr::SocketDatagramImplBSD] ERROR: Could not read from socket (%s:%hu): %s\n",
                        m_remote_addr.getAddressString().c_str(),
                        m_remote_addr.getPort(), strerror(errno));
                retval.setCode(Status::Failure);
            }
        }
        else {
            bytes_read = bytes;
        }
    }

    return retval;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
Status
SocketDatagramImplBSD::sendto (const void* msg, const vpr::Uint32 length,
                               const int flags, const InetAddr& to,
                               vpr::Uint32& bytes_sent,
                               const vpr::Interval timeout)
{
    Status retval;

    retval = m_handle->isWriteable(timeout);

    if ( retval.success() ) {
        ssize_t bytes;

        m_blocking_fixed = true;

        bytes = ::sendto(m_handle->m_fdesc, msg, length, flags,
                         (struct sockaddr*) &to.m_addr, to.size());

        if ( bytes == -1 ) {
            bytes_sent = 0;

            if ( errno == EAGAIN && getNonBlocking() ) {
                retval.setCode(Status::WouldBlock);
            }
            else {
                fprintf(stderr,
                        "[vpr::SocketDatagramImplBSD] ERROR: Could not send to %s:%hu on socket (%s:%hu): %s\n",
                        to.getAddressString().c_str(), to.getPort(),
                        m_remote_addr.getAddressString().c_str(),
                        m_remote_addr.getPort(), strerror(errno));
                retval.setCode(Status::Failure);
            }
        }
        else {
            bytes_sent = bytes;
        }
    }

    return retval;
}

}; // End of vpr namespace
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Intel Corporation. All rights reserved.
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "VaapiBuffer.h"

#include "VaapiUtils.h"
#include "vaapicontext.h"
#include "vaapidisplay.h"

namespace YamiMediaCodec {

BufObjectPtr VaapiBuffer::create(const ContextPtr& context,
    VABufferType type,
    uint32_t size,
    const void* data)
{
    BufObjectPtr buf;
    if (!context || !context->getDisplay())
        return buf;
    DisplayPtr display = context->getDisplay();
    VABufferID id;
    VAStatus status = vaCreateBuffer(display->getID(), context->getID(),
        type, size, 1, (void*)data, &id);
    if (!checkVaapiStatus(status, "vaCreateBuffer"))
        return buf;
    buf.reset(new VaapiBuffer(display, id, size));
    return buf;
}

void* VaapiBuffer::map()
{
    if (!m_data) {
        VAStatus status = vaMapBuffer(m_display->getID(), m_id, &m_data);
        if (!checkVaapiStatus(status, "vaMapBuffer")) {
            m_data = NULL;
        }
    }
    return m_data;
}

void VaapiBuffer::unmap()
{
    if (m_data) {
        checkVaapiStatus(vaUnmapBuffer(m_display->getID(), m_id), "vaUnmapBuffer");
        m_data = NULL;
    }
}

uint32_t VaapiBuffer::getSize()
{
    return m_size;
}

VABufferID VaapiBuffer::getID()
{
    return m_id;
}

VaapiBuffer::VaapiBuffer(const DisplayPtr& display, VABufferID id, uint32_t size)
    : m_display(display)
    , m_id(id)
    , m_data(NULL)
    , m_size(size)
{
}

VaapiBuffer::~VaapiBuffer()
{
    unmap();
    checkVaapiStatus(vaDestroyBuffer(m_display->getID(), m_id), "vaDestroyBuffer");
}
}
<commit_msg>vaapi: Don't create buffer when size is 0<commit_after>/*
 * Copyright (C) 2014 Intel Corporation. All rights reserved.
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "VaapiBuffer.h"

#include "VaapiUtils.h"
#include "vaapicontext.h"
#include "vaapidisplay.h"

namespace YamiMediaCodec {

BufObjectPtr VaapiBuffer::create(const ContextPtr& context,
    VABufferType type,
    uint32_t size,
    const void* data)
{
    BufObjectPtr buf;
    if (!size || !context || !context->getDisplay()){
        ERROR("vaapibuffer: can't create buffer");
        return buf;
    }
    DisplayPtr display = context->getDisplay();
    VABufferID id;
    VAStatus status = vaCreateBuffer(display->getID(), context->getID(),
        type, size, 1, (void*)data, &id);
    if (!checkVaapiStatus(status, "vaCreateBuffer"))
        return buf;
    buf.reset(new VaapiBuffer(display, id, size));
    return buf;
}

void* VaapiBuffer::map()
{
    if (!m_data) {
        VAStatus status = vaMapBuffer(m_display->getID(), m_id, &m_data);
        if (!checkVaapiStatus(status, "vaMapBuffer")) {
            m_data = NULL;
        }
    }
    return m_data;
}

void VaapiBuffer::unmap()
{
    if (m_data) {
        checkVaapiStatus(vaUnmapBuffer(m_display->getID(), m_id), "vaUnmapBuffer");
        m_data = NULL;
    }
}

uint32_t VaapiBuffer::getSize()
{
    return m_size;
}

VABufferID VaapiBuffer::getID()
{
    return m_id;
}

VaapiBuffer::VaapiBuffer(const DisplayPtr& display, VABufferID id, uint32_t size)
    : m_display(display)
    , m_id(id)
    , m_data(NULL)
    , m_size(size)
{
}

VaapiBuffer::~VaapiBuffer()
{
    unmap();
    checkVaapiStatus(vaDestroyBuffer(m_display->getID(), m_id), "vaDestroyBuffer");
}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval.cc,v 1.24 2001/12/03 04:47:15 steve Exp $"
#endif

# include "config.h"

# include  <iostream>

# include  "PExpr.h"
# include  "netlist.h"
# include  "compiler.h"

verinum* PExpr::eval_const(const Design*, const NetScope*) const
{
      return 0;
}

verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
{
      verinum*l = left_->eval_const(des, scope);
      if (l == 0) return 0;
      verinum*r = right_->eval_const(des, scope);
      if (r == 0) {
	    delete l;
	    return 0;
      }
      verinum*res;

      switch (op_) {
	  case '+': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv+rv, l->len());
		break;
	  }
	  case '-': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv-rv, l->len());
		break;
	  }
	  case '*': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv * rv, l->len());
		break;
	  }
	  case '/': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv / rv, l->len());
		break;
	  }
	  case '%': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv % rv, l->len());
		break;
	  }
	  case 'l': {
		assert(r->is_defined());
		unsigned long rv = r->as_ulong();
		res = new verinum(verinum::V0, l->len());
		if (rv < res->len()) {
		      unsigned cnt = res->len() - rv;
		      for (unsigned idx = 0 ;  idx < cnt ;  idx += 1)
			    res->set(idx+rv, l->get(idx));
		}
		break;
	  }

	  default:
	    delete l;
	    delete r;
	    return 0;
      }

      delete l;
      delete r;
      return res;
}

/*
 * Evaluate an identifier as a constant expression. This is only
 * possible if the identifier is that of a parameter.
 */
verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
{
      assert(scope);
      const NetExpr*expr = des->find_parameter(scope, path_);

      if (expr == 0)
	    return 0;

      assert(msb_ == 0);

      if (dynamic_cast<const NetEParam*>(expr)) {
	    cerr << get_line() << ": sorry: I cannot evaluate ``" <<
		  path_ << "'' in this scope: " << scope->name() << endl;
	    return 0;
      }

      const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
      assert(eval);
      return new verinum(eval->value());
}

verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
{
      long val = value_->as_long();
      return new verinum(val);
}

verinum* PENumber::eval_const(const Design*, const NetScope*) const
{
      return new verinum(value());
}

verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
{
      verinum*test = expr_->eval_const(des, scope);
      if (test == 0)
	    return 0;

      verinum::V bit = test->get(0);
      delete test;
      switch (bit) {
	  case verinum::V0:
	    return fal_->eval_const(des, scope);
	  case verinum::V1:
	    return tru_->eval_const(des, scope);
	  default:
	    return 0;
	      // XXXX It is possible to handle this case if both fal_
	      // and tru_ are constant. Someday...
      }
}

verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
{
      verinum*val = expr_->eval_const(des, scope);
      if (val == 0)
	    return 0;

      switch (op_) {
	  case '+':
	    return val;

	  case '-': {
		  /* We need to expand the value a bit if we are
		     taking the 2's complement so that we are
		     guaranteed to not overflow. */
		verinum tmp (0UL, val->len()+1);
		for (unsigned idx = 0 ;  idx < val->len() ;  idx += 1)
		      tmp.set(idx, val->get(idx));

		*val = v_not(tmp) + verinum(verinum::V1, 1);
		val->has_sign(true);
		return val;
	  }

      }
	    delete val;
      return 0;
}

/*
 * $Log: eval.cc,v $
 * Revision 1.24  2001/12/03 04:47:15  steve
 *  Parser and pform use hierarchical names as hname_t
 *  objects instead of encoded strings.
 *
 * Revision 1.23  2001/11/07 04:01:59  steve
 *  eval_const uses scope instead of a string path.
 *
 * Revision 1.22  2001/11/06 06:11:55  steve
 *  Support more real arithmetic in delay constants.
 *
 * Revision 1.21  2001/07/25 03:10:49  steve
 *  Create a config.h.in file to hold all the config
 *  junk, and support gcc 3.0. (Stephan Boettcher)
 *
 * Revision 1.20  2001/02/09 02:49:59  steve
 *  Be more clear about scope of failure.
 *
 * Revision 1.19  2001/01/27 05:41:48  steve
 *  Fix sign extension of evaluated constants. (PR#91)
 *
 * Revision 1.18  2001/01/14 23:04:56  steve
 *  Generalize the evaluation of floating point delays, and
 *  get it working with delay assignment statements.
 *
 *  Allow parameters to be referenced by hierarchical name.
 *
 * Revision 1.17  2001/01/04 04:47:51  steve
 *  Add support for << is signal indices.
 *
 * Revision 1.16  2000/12/10 22:01:36  steve
 *  Support decimal constants in behavioral delays.
 *
 * Revision 1.15  2000/09/07 22:38:13  steve
 *  Support unary + and - in constants.
 */

<commit_msg> Evaluate constant right shifts.<commit_after>/*
 * Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval.cc,v 1.25 2001/12/29 00:43:55 steve Exp $"
#endif

# include "config.h"

# include  <iostream>

# include  "PExpr.h"
# include  "netlist.h"
# include  "compiler.h"

verinum* PExpr::eval_const(const Design*, const NetScope*) const
{
      return 0;
}

verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
{
      verinum*l = left_->eval_const(des, scope);
      if (l == 0) return 0;
      verinum*r = right_->eval_const(des, scope);
      if (r == 0) {
	    delete l;
	    return 0;
      }
      verinum*res;

      switch (op_) {
	  case '+': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv+rv, l->len());
		break;
	  }
	  case '-': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv-rv, l->len());
		break;
	  }
	  case '*': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv * rv, l->len());
		break;
	  }
	  case '/': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv / rv, l->len());
		break;
	  }
	  case '%': {
		assert(l->is_defined());
		assert(r->is_defined());
		long lv = l->as_long();
		long rv = r->as_long();
		res = new verinum(lv % rv, l->len());
		break;
	  }
	  case 'l': { // left shift (<<)
		assert(r->is_defined());
		unsigned long rv = r->as_ulong();
		res = new verinum(verinum::V0, l->len());
		if (rv < res->len()) {
		      unsigned cnt = res->len() - rv;
		      for (unsigned idx = 0 ;  idx < cnt ;  idx += 1)
			    res->set(idx+rv, l->get(idx));
		}
		break;
	  }
	  case 'r': { // right shift (>>)
		assert(r->is_defined());
		unsigned long rv = r->as_ulong();
		res = new verinum(verinum::V0, l->len());
		if (rv < res->len()) {
		      unsigned cnt = res->len() - rv;
		      for (unsigned idx = 0 ;  idx < cnt ;  idx += 1)
			    res->set(idx, l->get(idx+rv));
		}
		break;
	  }

	  default:
	    delete l;
	    delete r;
	    return 0;
      }

      delete l;
      delete r;
      return res;
}

/*
 * Evaluate an identifier as a constant expression. This is only
 * possible if the identifier is that of a parameter.
 */
verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
{
      assert(scope);
      const NetExpr*expr = des->find_parameter(scope, path_);

      if (expr == 0)
	    return 0;

      assert(msb_ == 0);

      if (dynamic_cast<const NetEParam*>(expr)) {
	    cerr << get_line() << ": sorry: I cannot evaluate ``" <<
		  path_ << "'' in this scope: " << scope->name() << endl;
	    return 0;
      }

      const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
      assert(eval);
      return new verinum(eval->value());
}

verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
{
      long val = value_->as_long();
      return new verinum(val);
}

verinum* PENumber::eval_const(const Design*, const NetScope*) const
{
      return new verinum(value());
}

verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
{
      verinum*test = expr_->eval_const(des, scope);
      if (test == 0)
	    return 0;

      verinum::V bit = test->get(0);
      delete test;
      switch (bit) {
	  case verinum::V0:
	    return fal_->eval_const(des, scope);
	  case verinum::V1:
	    return tru_->eval_const(des, scope);
	  default:
	    return 0;
	      // XXXX It is possible to handle this case if both fal_
	      // and tru_ are constant. Someday...
      }
}

verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
{
      verinum*val = expr_->eval_const(des, scope);
      if (val == 0)
	    return 0;

      switch (op_) {
	  case '+':
	    return val;

	  case '-': {
		  /* We need to expand the value a bit if we are
		     taking the 2's complement so that we are
		     guaranteed to not overflow. */
		verinum tmp (0UL, val->len()+1);
		for (unsigned idx = 0 ;  idx < val->len() ;  idx += 1)
		      tmp.set(idx, val->get(idx));

		*val = v_not(tmp) + verinum(verinum::V1, 1);
		val->has_sign(true);
		return val;
	  }

      }
	    delete val;
      return 0;
}

/*
 * $Log: eval.cc,v $
 * Revision 1.25  2001/12/29 00:43:55  steve
 *  Evaluate constant right shifts.
 *
 * Revision 1.24  2001/12/03 04:47:15  steve
 *  Parser and pform use hierarchical names as hname_t
 *  objects instead of encoded strings.
 *
 * Revision 1.23  2001/11/07 04:01:59  steve
 *  eval_const uses scope instead of a string path.
 *
 * Revision 1.22  2001/11/06 06:11:55  steve
 *  Support more real arithmetic in delay constants.
 *
 * Revision 1.21  2001/07/25 03:10:49  steve
 *  Create a config.h.in file to hold all the config
 *  junk, and support gcc 3.0. (Stephan Boettcher)
 *
 * Revision 1.20  2001/02/09 02:49:59  steve
 *  Be more clear about scope of failure.
 *
 * Revision 1.19  2001/01/27 05:41:48  steve
 *  Fix sign extension of evaluated constants. (PR#91)
 *
 * Revision 1.18  2001/01/14 23:04:56  steve
 *  Generalize the evaluation of floating point delays, and
 *  get it working with delay assignment statements.
 *
 *  Allow parameters to be referenced by hierarchical name.
 *
 * Revision 1.17  2001/01/04 04:47:51  steve
 *  Add support for << is signal indices.
 *
 * Revision 1.16  2000/12/10 22:01:36  steve
 *  Support decimal constants in behavioral delays.
 *
 * Revision 1.15  2000/09/07 22:38:13  steve
 *  Support unary + and - in constants.
 */

<|endoftext|>


<commit_before>#include <string>
#include <cassert>

#include "parlex/details/subjob.hpp"
#include "parlex/details/context.hpp"
#include "parlex/details/job.hpp"
#include "parlex/recognizer.hpp"
#include "parlex/parser.hpp"
#include "parlex/state_machine.hpp"

namespace parlex {
namespace details {

subjob::subjob(
	job & owner,
	state_machine_base const & machine,
	int documentPosition
):
	producer(owner, machine, documentPosition),
	machine(machine),
	lifetimeCounter(1) //see finish_creation
{
	//DBG("constructed subjob b:", documentPosition, " m:", machine);
}

subjob::~subjob() {
	//DBG("destructing subjob b:", documentPosition, " m:", machine);
}

void subjob::start() {
	{
		std::unique_lock<std::mutex> lock(mutex);
		contexts.emplace_back(*this, context_ref(), document_position, nullptr);
	}
	machine.start(*this, document_position);
	end_dependency(); //reference code B
}

context_ref subjob::construct_start_state_context(int documentPosition) {
	std::unique_lock<std::mutex> lock(mutex);
	contexts.emplace_back(*this, context_ref(), documentPosition, nullptr);
	return contexts.back().get_ref();
}

context_ref subjob::construct_stepped_context(context_ref const & prior, match fromTransition) {
	std::unique_lock<std::mutex> lock(mutex);
	contexts.emplace_back(*this, prior, prior.current_document_position() + fromTransition.consumed_character_count, &fromTransition);
	return contexts.back().get_ref();
}

void subjob::on(context_ref const & c, recognizer const & r, int nextDfaState) {
	increment_lifetime(); //reference code C
	owner.connect(match_class(r, c.current_document_position()), c, nextDfaState);
}

void subjob::accept(context_ref const & c) {
	assert(&c.owner() == this);
	permutation p = c.result();
	//DBG("Accepting r:", r.id, " p:", documentPosition, " l:", c.current_document_position() - documentPosition);
	if (!machine.filter) {
		int len = c.current_document_position() - c.owner().document_position;
		enque_permutation(len, p);
	} else {
		std::unique_lock<std::mutex> lock(mutex);
		queuedPermutations.push_back(p);
	}
}

void subjob::decrement_lifetime() {
	int temp = --lifetimeCounter;
	//DBG("decrement_lifetime m:", machine, " b:", documentPosition, " r:", temp);
	if (temp > 0) {
		return;
	}
	flush();
	terminate();
}

void subjob::end_dependency()
{
	//DBG("end_dependency m:", machine, " b:", documentPosition);
	decrement_lifetime();
}

void subjob::finish_creation() {
	//DBG("finish_creation m:", machine, " b:", documentPosition);
	decrement_lifetime();
}

void subjob::increment_lifetime() {
	int temp = ++lifetimeCounter;
	assert(temp > 1);
	//DBG("increment_lifetime m:", machine, " b:", documentPosition, " r:", temp);
}

void subjob::flush() {
	///DBG("flush m:", machine, " b:", documentPosition);
	if (machine.filter != nullptr) {
		std::unique_lock<std::mutex> lock(mutex);
		if (queuedPermutations.size() == 0) {
			return;
		}
		std::set<int> selections = (*machine.filter)(owner.document, queuedPermutations);
		int counter = 0;
		for (auto const & permutation : queuedPermutations) {
			if (selections.count(counter) > 0) {
				int len = permutation.size() > 0 ? permutation.back().document_position + permutation.back().consumed_character_count - document_position : 0;
				enque_permutation(len, permutation);
			}
			counter++;
		}
	}
}

}
}
<commit_msg>Make proving termination of parlex a bit easier<commit_after>#include <string>
#include <cassert>

#include "parlex/details/subjob.hpp"
#include "parlex/details/context.hpp"
#include "parlex/details/job.hpp"
#include "parlex/recognizer.hpp"
#include "parlex/parser.hpp"
#include "parlex/state_machine.hpp"

namespace parlex {
namespace details {

subjob::subjob(
	job & owner,
	state_machine_base const & machine,
	int documentPosition
):
	producer(owner, machine, documentPosition),
	machine(machine),
	lifetimeCounter(1) //see finish_creation
{
	//DBG("constructed subjob b:", documentPosition, " m:", machine);
}

subjob::~subjob() {
	//DBG("destructing subjob b:", documentPosition, " m:", machine);
}

void subjob::start() {
	{
		std::unique_lock<std::mutex> lock(mutex);
		contexts.emplace_back(*this, context_ref(), document_position, nullptr);
	}
	machine.start(*this, document_position);
	end_dependency(); //reference code B
}

context_ref subjob::construct_start_state_context(int documentPosition) {
	std::unique_lock<std::mutex> lock(mutex);
	contexts.emplace_back(*this, context_ref(), documentPosition, nullptr);
	return contexts.back().get_ref();
}

context_ref subjob::construct_stepped_context(context_ref const & prior, match fromTransition) {
	std::unique_lock<std::mutex> lock(mutex);
	contexts.emplace_back(*this, prior, prior.current_document_position() + fromTransition.consumed_character_count, &fromTransition);
	return contexts.back().get_ref();
}

void subjob::on(context_ref const & c, recognizer const & r, int nextDfaState) {
	if (c.current_document_position() >= c.owner().owner.document.length()) {
		return;
	}
	increment_lifetime(); //reference code C
	owner.connect(match_class(r, c.current_document_position()), c, nextDfaState);
}

void subjob::accept(context_ref const & c) {
	assert(&c.owner() == this);
	permutation p = c.result();
	//DBG("Accepting r:", r.id, " p:", documentPosition, " l:", c.current_document_position() - documentPosition);
	if (!machine.filter) {
		int len = c.current_document_position() - c.owner().document_position;
		enque_permutation(len, p);
	} else {
		std::unique_lock<std::mutex> lock(mutex);
		queuedPermutations.push_back(p);
	}
}

void subjob::decrement_lifetime() {
	int temp = --lifetimeCounter;
	//DBG("decrement_lifetime m:", machine, " b:", documentPosition, " r:", temp);
	if (temp > 0) {
		return;
	}
	flush();
	terminate();
}

void subjob::end_dependency()
{
	//DBG("end_dependency m:", machine, " b:", documentPosition);
	decrement_lifetime();
}

void subjob::finish_creation() {
	//DBG("finish_creation m:", machine, " b:", documentPosition);
	decrement_lifetime();
}

void subjob::increment_lifetime() {
	int temp = ++lifetimeCounter;
	assert(temp > 1);
	//DBG("increment_lifetime m:", machine, " b:", documentPosition, " r:", temp);
}

void subjob::flush() {
	///DBG("flush m:", machine, " b:", documentPosition);
	if (machine.filter != nullptr) {
		std::unique_lock<std::mutex> lock(mutex);
		if (queuedPermutations.size() == 0) {
			return;
		}
		std::set<int> selections = (*machine.filter)(owner.document, queuedPermutations);
		int counter = 0;
		for (auto const & permutation : queuedPermutations) {
			if (selections.count(counter) > 0) {
				int len = permutation.size() > 0 ? permutation.back().document_position + permutation.back().consumed_character_count - document_position : 0;
				enque_permutation(len, permutation);
			}
			counter++;
		}
	}
}

}
}
<|endoftext|>


<commit_before>#include "alsa.hpp"
#include <audio_io/audio_io.hpp>
#include <audio_io/private/audio_outputs.hpp>
#include <audio_io/private/sample_format_converter.hpp>
#include <vector>
#include <string>
#include <functional>
#include <thread>
#include <atomic>
#include <alsa/asoundlib.h>

namespace audio_io {
namespace implementation {

AlsaOutputDevice::AlsaOutputDevice(std::function<void(float*, int)> callback, std::string name, int sr, int channels, int blockSize, float minLatency, float startLatency, float maxLatency) {
	snd_pcm_hw_params_t *params;
	snd_pcm_hw_params_alloca(&params);
	int res = snd_pcm_open(&device_handle, name.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
	if(res) {
		throw AudioIOError("An Alsa Error occurred.");
	}
	res = snd_pcm_hw_params_any(device_handle, params);
	if(res < 0) {
		throw AudioIOError("Alsa: could not configuer PCM device.");
	}
	//TODO: this doesn't deal with endianness properly, and uses our knowledge that x86 is little endian.
	res = snd_pcm_hw_params_set_format(device_handle, params, SND_PCM_FORMAT_FLOAT_LE);
	if(res < 0) {
		throw AudioIOError("ALSA: Couldn't get little endian float.");
	}
	unsigned int alsaChannels = channels;
	res = snd_pcm_hw_params_set_channels_near (device_handle, params, &alsaChannels);
	if(res < 0) {
		throw AudioIOError("Couldn't constrain channel count.");
	}
	unsigned int alsaSr = sr;
	res = snd_pcm_hw_params_set_rate_near(device_handle, params, &alsaSr, 0);
	if(res < 0) {
		throw AudioIOError("ALSA: Couldn't constrain sample rate.");
	}
	res = snd_pcm_hw_params_set_access(device_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
	if(res < 0) {
		throw AudioIOError("ALSA: couldn't set access.");
	}
	//compute needed buffer size.
	snd_pcm_uframes_t alsaBufferSize = alsaSr*maxLatency;
	res = snd_pcm_hw_params_set_buffer_size_near(device_handle, params, &alsaBufferSize);
	if(res < 0) {
		throw AudioIOError("ALSA: couldn't set buffer size.");
	}
	res = snd_pcm_hw_params(device_handle, params);
	if(res < 0) {
		throw AudioIOError("ALSA: Could not prepare device.");
	}
	init(callback, blockSize, channels, sr, (int)alsaChannels, (int)alsaSr);
	worker_running.test_and_set();
	worker_thread = std::thread([&] () {workerThreadFunction();});
}

AlsaOutputDevice::~AlsaOutputDevice() {
	stop();
}

void AlsaOutputDevice::stop() {
	if(stopped == false) {
		if(worker_thread.joinable()) {
			worker_running.clear();
			worker_thread.join();
		}
	}
	stopped = true;
}

void AlsaOutputDevice::workerThreadFunction() {
	float* buffer = new float[output_channels*output_frames];
	while(worker_running.test_and_set()) {
		sample_format_converter->write(output_frames, buffer);
		snd_pcm_sframes_t res = snd_pcm_writei(device_handle, buffer, (snd_pcm_uframes_t)output_frames);
		if(res < 0) {
			snd_pcm_prepare(device_handle);
		}
	}
	snd_pcm_drain(device_handle);
	snd_pcm_close(device_handle);
}

}
}<commit_msg>Be a bit smarter about periods.<commit_after>#include "alsa.hpp"
#include <audio_io/audio_io.hpp>
#include <audio_io/private/audio_outputs.hpp>
#include <audio_io/private/sample_format_converter.hpp>
#include <vector>
#include <string>
#include <functional>
#include <thread>
#include <atomic>
#include <algorithm>
#include <alsa/asoundlib.h>

namespace audio_io {
namespace implementation {

AlsaOutputDevice::AlsaOutputDevice(std::function<void(float*, int)> callback, std::string name, int sr, int channels, int blockSize, float minLatency, float startLatency, float maxLatency) {
	snd_pcm_hw_params_t *params;
	snd_pcm_hw_params_alloca(&params);
	int res = snd_pcm_open(&device_handle, name.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
	if(res) {
		throw AudioIOError("An Alsa Error occurred.");
	}
	res = snd_pcm_hw_params_any(device_handle, params);
	if(res < 0) {
		throw AudioIOError("Alsa: could not configuer PCM device.");
	}
	//TODO: this doesn't deal with endianness properly, and uses our knowledge that x86 is little endian.
	res = snd_pcm_hw_params_set_format(device_handle, params, SND_PCM_FORMAT_FLOAT_LE);
	if(res < 0) {
		throw AudioIOError("ALSA: Couldn't get little endian float.");
	}
	unsigned int alsaChannels = channels;
	res = snd_pcm_hw_params_set_channels_near (device_handle, params, &alsaChannels);
	if(res < 0) {
		throw AudioIOError("Couldn't constrain channel count.");
	}
	unsigned int alsaSr = sr;
	res = snd_pcm_hw_params_set_rate_near(device_handle, params, &alsaSr, 0);
	if(res < 0) {
		throw AudioIOError("ALSA: Couldn't constrain sample rate.");
	}
	res = snd_pcm_hw_params_set_access(device_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
	if(res < 0) {
		throw AudioIOError("ALSA: couldn't set access.");
	}
	//Use 10 milliseconds (1 ms = 1000 us).
	//No app is likely to go below this, nor should we.
	unsigned int alsaPeriodMicrosecs = 10000;
	res = snd_pcm_hw_params_set_period_time_near(device_handle, params, &alsaPeriodMicrosecs, 0);
	if(res < 0) {
		throw AudioIOError("ALSA: couldn't configure period time.");
	}
	//compute needed buffer size and bump maxLatency if needed.
	maxLatency = std::max<double>(maxLatency, 2.3*blockSize/(double)sr);
	snd_pcm_uframes_t alsaBufferSize = alsaSr*maxLatency;

	res = snd_pcm_hw_params_set_buffer_size_near(device_handle, params, &alsaBufferSize);
	if(res < 0) {
		throw AudioIOError("ALSA: couldn't set buffer size.");
	}
	res = snd_pcm_hw_params(device_handle, params);
	if(res < 0) {
		throw AudioIOError("ALSA: Could not prepare device.");
	}
	init(callback, blockSize, channels, sr, (int)alsaChannels, (int)alsaSr);
	worker_running.test_and_set();
	worker_thread = std::thread([&] () {workerThreadFunction();});
}

AlsaOutputDevice::~AlsaOutputDevice() {
	stop();
}

void AlsaOutputDevice::stop() {
	if(stopped == false) {
		if(worker_thread.joinable()) {
			worker_running.clear();
			worker_thread.join();
		}
	}
	stopped = true;
}

void AlsaOutputDevice::workerThreadFunction() {
	float* buffer = new float[output_channels*output_frames]();
	while(worker_running.test_and_set()) {
		sample_format_converter->write(output_frames, buffer);
		snd_pcm_sframes_t res = snd_pcm_writei(device_handle, buffer, (snd_pcm_uframes_t)output_frames);
		if(res < 0) {
			snd_pcm_prepare(device_handle);
		}
	}
	snd_pcm_drain(device_handle);
	snd_pcm_close(device_handle);
	delete[] buffer;
}

}
}<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

// Parts of this code sourced from SnopyDogy
// https://gist.github.com/SnopyDogy/a9a22497a893ec86aa3e

#if defined(WITH_GRAPHICS)

// cuda_gl_interop.h does not include OpenGL headers for ARM
//#if defined(__arm__) || defined (__aarch64__)
#include <glbinding/gl/gl.h>
#include <glbinding/Binding.h>
//#endif

#include <platform.hpp>
#include <graphics_common.hpp>

#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>

#include <map>

using af::dim4;

namespace cuda
{

typedef std::map<void *, cudaGraphicsResource *> interop_t;
typedef interop_t::iterator iter_t;

// Manager Class for cudaPBOResource: calls garbage collection at the end of the program
class InteropManager
{
    private:
        interop_t interop_maps[DeviceManager::MAX_DEVICES];

    public:
        static InteropManager& getInstance();
        static bool checkGraphicsInteropCapability();

        ~InteropManager();
        cudaGraphicsResource* getBufferResource(const forge::Image* handle);
        cudaGraphicsResource* getBufferResource(const forge::Plot* handle);
        cudaGraphicsResource* getBufferResource(const forge::Histogram* handle);
        cudaGraphicsResource* getBufferResource(const forge::Surface* handle);

    protected:
        InteropManager() {}
        InteropManager(InteropManager const&);
        void operator=(InteropManager const&);
        void destroyResources();
};

}

#endif
<commit_msg>GL Header fix for cuda_gl_interop on ARM/Tegra<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

// Parts of this code sourced from SnopyDogy
// https://gist.github.com/SnopyDogy/a9a22497a893ec86aa3e

#if defined(WITH_GRAPHICS)

// cuda_gl_interop.h does not include OpenGL headers for ARM
#include <glbinding/gl/gl.h>
#include <glbinding/Binding.h>

#if defined(__arm__) || defined(__aarch64__)
using namespace gl;
#define GL_VERSION gl::GL_VERSION
#endif

#include <platform.hpp>
#include <graphics_common.hpp>

#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>

#include <map>

using af::dim4;

namespace cuda
{

typedef std::map<void *, cudaGraphicsResource *> interop_t;
typedef interop_t::iterator iter_t;

// Manager Class for cudaPBOResource: calls garbage collection at the end of the program
class InteropManager
{
    private:
        interop_t interop_maps[DeviceManager::MAX_DEVICES];

    public:
        static InteropManager& getInstance();
        static bool checkGraphicsInteropCapability();

        ~InteropManager();
        cudaGraphicsResource* getBufferResource(const forge::Image* handle);
        cudaGraphicsResource* getBufferResource(const forge::Plot* handle);
        cudaGraphicsResource* getBufferResource(const forge::Histogram* handle);
        cudaGraphicsResource* getBufferResource(const forge::Surface* handle);

    protected:
        InteropManager() {}
        InteropManager(InteropManager const&);
        void operator=(InteropManager const&);
        void destroyResources();
};

}

#endif
<|endoftext|>


<commit_before>// @(#)root/tree:$Id$
// Author: Rene Brun   12/01/96

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

////////////////////////////////////////////////////////////////////////////////
/// \class TLeafB
/// A TLeaf for an 8 bit Integer data type. \f$(x_1,y_1)\f$

#include "TLeafB.h"
#include "TBranch.h"
#include "TClonesArray.h"
#include "Riostream.h"

ClassImp(TLeafB)

////////////////////////////////////////////////////////////////////////////////
/// Default constructor.

TLeafB::TLeafB()
: TLeaf()
, fMinimum(0)
, fMaximum(0)
, fValue(0)
, fPointer(0)
{
   fLenType = 1;
}

////////////////////////////////////////////////////////////////////////////////
/// Create a LeafB.

TLeafB::TLeafB(TBranch *parent, const char* name, const char* type)
   : TLeaf(parent, name, type)
   , fMinimum(0)
   , fMaximum(0)
   , fValue(0)
   , fPointer(0)
{
   fLenType = 1;
}

////////////////////////////////////////////////////////////////////////////////
/// Destructor.

TLeafB::~TLeafB()
{
   if (ResetAddress(0, kTRUE)) {
      delete[] fValue;
      fValue = 0;
   }
   // Note: We do not own this, the user's object does.
   fPointer = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Export element from local leaf buffer to a ClonesArray.

void TLeafB::Export(TClonesArray* list, Int_t n)
{
   for (Int_t i = 0, j = 0; i < n; i++, j += fLen) {
      memcpy(((char*) list->UncheckedAt(i)) + fOffset, &fValue[j], fLen);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Pack leaf elements into Basket output buffer.

void TLeafB::FillBasket(TBuffer& b)
{
   Int_t len = GetLen();
   if (fPointer) {
      fValue = *fPointer;
   }
   if (IsRange()) {
      if (fValue[0] > fMaximum) {
         fMaximum = fValue[0];
      }
   }
   if (IsUnsigned()) {
      for (Int_t i = 0; i < len; i++) {
         b << (UChar_t) fValue[i];
      }
   } else {
      b.WriteFastArray(fValue, len);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Returns name of leaf type.

const char *TLeafB::GetTypeName() const
{
   if (fIsUnsigned) {
      return "UChar_t";
   }
   return "Char_t";
}

////////////////////////////////////////////////////////////////////////////////
/// Import element from ClonesArray into local leaf buffer.

void TLeafB::Import(TClonesArray *list, Int_t n)
{
   for (Int_t i = 0, j = 0; i < n; i++, j+= fLen) {
      memcpy(&fValue[j], ((char*) list->UncheckedAt(i)) + fOffset, fLen);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Prints leaf value.

void TLeafB::PrintValue(Int_t l) const
{
   if (fIsUnsigned) {
      UChar_t *uvalue = (UChar_t*) GetValuePointer();
      printf("%u", uvalue[l]);
   } else {
      Char_t *value = (Char_t*) GetValuePointer();
      printf("%d", value[l]);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Read leaf elements from Basket input buffer.

void TLeafB::ReadBasket(TBuffer &b)
{
   if (!fLeafCount && (fNdata == 1)) {
      b.ReadChar(fValue[0]);
   } else {
      if (fLeafCount) {
         Long64_t entry = fBranch->GetReadEntry();
         if (fLeafCount->GetBranch()->GetReadEntry() != entry) {
            fLeafCount->GetBranch()->GetEntry(entry);
         }
         Int_t len = Int_t(fLeafCount->GetValue());
         if (len > fLeafCount->GetMaximum()) {
            Error("ReadBasket", "leaf: '%s' len: %d max: %d", GetName(), len, fLeafCount->GetMaximum());
            len = fLeafCount->GetMaximum();
         }
         fNdata = len * fLen;
         b.ReadFastArray(fValue, len*fLen);
      } else {
         b.ReadFastArray(fValue, fLen);
      }
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Read leaf elements from Basket input buffer and export buffer to
/// TClonesArray objects.

void TLeafB::ReadBasketExport(TBuffer& b, TClonesArray* list, Int_t n)
{
   b.ReadFastArray(fValue, n*fLen);

   for (Int_t i = 0, j = 0; i < n; i++, j += fLen) {
      memcpy(((char*) list->UncheckedAt(i)) + fOffset, &fValue[j], fLen);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Read a 8 bit integer from std::istream s and store it into the branch buffer.

void TLeafB::ReadValue(std::istream &s, Char_t /*delim = ' '*/)
{
   if (fIsUnsigned) {
      UChar_t *uvalue = (UChar_t*)GetValuePointer();
      for (Int_t i=0;i<fLen;i++) {
         UShort_t tmp;
         s >> tmp;
         uvalue[i] = tmp;
      }
   } else {
      Char_t *value = (Char_t*)GetValuePointer();
      for (Int_t i=0;i<fLen;i++) {
         Short_t tmp;
         s >> tmp;
         value[i] = tmp;
      }
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Set value buffer address.

void TLeafB::SetAddress(void *addr)
{
   // Check ownership of the value buffer and
   // calculate a new size for it.
   if (ResetAddress(addr)) {
      // -- We owned the old value buffer, delete it.
      delete[] fValue;
      fValue = 0;
   }
   if (addr) {
      // -- We have been provided a new value buffer.
      if (TestBit(kIndirectAddress)) {
         // -- The data member is a pointer to an array.
         fPointer = (Char_t**) addr;
         // Calculate the maximum size we have ever needed
         // for the value buffer.
         Int_t ncountmax = fLen;
         if (fLeafCount) {
            ncountmax = (fLeafCount->GetMaximum() + 1) * fLen;
         }
         // Reallocate the value buffer if needed.
         if ((fLeafCount && (Int_t(fLeafCount->GetValue()) < ncountmax)) ||
             (fNdata < ncountmax) ||
             (*fPointer == 0)) {
            // -- Reallocate.
            // Note:
            //      1) For a varying length array we do this based on
            //         an indirect estimator of the size of the value
            //         buffer since we have no record of how large it
            //         actually is.  If the current length of the
            //         varying length array is less than it has been
            //         in the past, then reallocate the value buffer
            //         to the larger of either the calculated new size
            //         or the maximum size it has ever been.
            //
            //      2) The second condition checks if the new value
            //         buffer size calculated by ResetAddress() is
            //         smaller than the most we have ever used, and
            //         if it is, then we increase the new size and
            //         reallocate.
            //
            //      3) The third condition is checking to see if we
            //         have been given a value buffer, if not then
            //         we must allocate one.
            //
            if (fNdata < ncountmax) {
               fNdata = ncountmax;
            }
            delete[] *fPointer;
            *fPointer = 0;
            *fPointer = new Char_t[fNdata];
         }
         fValue = *fPointer;
      } else {
         // -- The data member is fixed size.
         // FIXME: What about fPointer???
         fValue = (char*) addr;
      }
   } else {
      // -- We must create the value buffer ourselves.
      // Note: We are using the size calculated by ResetAddress().
      fValue = new char[fNdata];
      // FIXME: Why initialize at all?
      fValue[0] = 0;
   }
}

<commit_msg>remove typo<commit_after>// @(#)root/tree:$Id$
// Author: Rene Brun   12/01/96

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

////////////////////////////////////////////////////////////////////////////////
/// \class TLeafB
/// A TLeaf for an 8 bit Integer data type.

#include "TLeafB.h"
#include "TBranch.h"
#include "TClonesArray.h"
#include "Riostream.h"

ClassImp(TLeafB)

////////////////////////////////////////////////////////////////////////////////
/// Default constructor.

TLeafB::TLeafB()
: TLeaf()
, fMinimum(0)
, fMaximum(0)
, fValue(0)
, fPointer(0)
{
   fLenType = 1;
}

////////////////////////////////////////////////////////////////////////////////
/// Create a LeafB.

TLeafB::TLeafB(TBranch *parent, const char* name, const char* type)
   : TLeaf(parent, name, type)
   , fMinimum(0)
   , fMaximum(0)
   , fValue(0)
   , fPointer(0)
{
   fLenType = 1;
}

////////////////////////////////////////////////////////////////////////////////
/// Destructor.

TLeafB::~TLeafB()
{
   if (ResetAddress(0, kTRUE)) {
      delete[] fValue;
      fValue = 0;
   }
   // Note: We do not own this, the user's object does.
   fPointer = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Export element from local leaf buffer to a ClonesArray.

void TLeafB::Export(TClonesArray* list, Int_t n)
{
   for (Int_t i = 0, j = 0; i < n; i++, j += fLen) {
      memcpy(((char*) list->UncheckedAt(i)) + fOffset, &fValue[j], fLen);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Pack leaf elements into Basket output buffer.

void TLeafB::FillBasket(TBuffer& b)
{
   Int_t len = GetLen();
   if (fPointer) {
      fValue = *fPointer;
   }
   if (IsRange()) {
      if (fValue[0] > fMaximum) {
         fMaximum = fValue[0];
      }
   }
   if (IsUnsigned()) {
      for (Int_t i = 0; i < len; i++) {
         b << (UChar_t) fValue[i];
      }
   } else {
      b.WriteFastArray(fValue, len);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Returns name of leaf type.

const char *TLeafB::GetTypeName() const
{
   if (fIsUnsigned) {
      return "UChar_t";
   }
   return "Char_t";
}

////////////////////////////////////////////////////////////////////////////////
/// Import element from ClonesArray into local leaf buffer.

void TLeafB::Import(TClonesArray *list, Int_t n)
{
   for (Int_t i = 0, j = 0; i < n; i++, j+= fLen) {
      memcpy(&fValue[j], ((char*) list->UncheckedAt(i)) + fOffset, fLen);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Prints leaf value.

void TLeafB::PrintValue(Int_t l) const
{
   if (fIsUnsigned) {
      UChar_t *uvalue = (UChar_t*) GetValuePointer();
      printf("%u", uvalue[l]);
   } else {
      Char_t *value = (Char_t*) GetValuePointer();
      printf("%d", value[l]);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Read leaf elements from Basket input buffer.

void TLeafB::ReadBasket(TBuffer &b)
{
   if (!fLeafCount && (fNdata == 1)) {
      b.ReadChar(fValue[0]);
   } else {
      if (fLeafCount) {
         Long64_t entry = fBranch->GetReadEntry();
         if (fLeafCount->GetBranch()->GetReadEntry() != entry) {
            fLeafCount->GetBranch()->GetEntry(entry);
         }
         Int_t len = Int_t(fLeafCount->GetValue());
         if (len > fLeafCount->GetMaximum()) {
            Error("ReadBasket", "leaf: '%s' len: %d max: %d", GetName(), len, fLeafCount->GetMaximum());
            len = fLeafCount->GetMaximum();
         }
         fNdata = len * fLen;
         b.ReadFastArray(fValue, len*fLen);
      } else {
         b.ReadFastArray(fValue, fLen);
      }
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Read leaf elements from Basket input buffer and export buffer to
/// TClonesArray objects.

void TLeafB::ReadBasketExport(TBuffer& b, TClonesArray* list, Int_t n)
{
   b.ReadFastArray(fValue, n*fLen);

   for (Int_t i = 0, j = 0; i < n; i++, j += fLen) {
      memcpy(((char*) list->UncheckedAt(i)) + fOffset, &fValue[j], fLen);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Read a 8 bit integer from std::istream s and store it into the branch buffer.

void TLeafB::ReadValue(std::istream &s, Char_t /*delim = ' '*/)
{
   if (fIsUnsigned) {
      UChar_t *uvalue = (UChar_t*)GetValuePointer();
      for (Int_t i=0;i<fLen;i++) {
         UShort_t tmp;
         s >> tmp;
         uvalue[i] = tmp;
      }
   } else {
      Char_t *value = (Char_t*)GetValuePointer();
      for (Int_t i=0;i<fLen;i++) {
         Short_t tmp;
         s >> tmp;
         value[i] = tmp;
      }
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Set value buffer address.

void TLeafB::SetAddress(void *addr)
{
   // Check ownership of the value buffer and
   // calculate a new size for it.
   if (ResetAddress(addr)) {
      // -- We owned the old value buffer, delete it.
      delete[] fValue;
      fValue = 0;
   }
   if (addr) {
      // -- We have been provided a new value buffer.
      if (TestBit(kIndirectAddress)) {
         // -- The data member is a pointer to an array.
         fPointer = (Char_t**) addr;
         // Calculate the maximum size we have ever needed
         // for the value buffer.
         Int_t ncountmax = fLen;
         if (fLeafCount) {
            ncountmax = (fLeafCount->GetMaximum() + 1) * fLen;
         }
         // Reallocate the value buffer if needed.
         if ((fLeafCount && (Int_t(fLeafCount->GetValue()) < ncountmax)) ||
             (fNdata < ncountmax) ||
             (*fPointer == 0)) {
            // -- Reallocate.
            // Note:
            //      1) For a varying length array we do this based on
            //         an indirect estimator of the size of the value
            //         buffer since we have no record of how large it
            //         actually is.  If the current length of the
            //         varying length array is less than it has been
            //         in the past, then reallocate the value buffer
            //         to the larger of either the calculated new size
            //         or the maximum size it has ever been.
            //
            //      2) The second condition checks if the new value
            //         buffer size calculated by ResetAddress() is
            //         smaller than the most we have ever used, and
            //         if it is, then we increase the new size and
            //         reallocate.
            //
            //      3) The third condition is checking to see if we
            //         have been given a value buffer, if not then
            //         we must allocate one.
            //
            if (fNdata < ncountmax) {
               fNdata = ncountmax;
            }
            delete[] *fPointer;
            *fPointer = 0;
            *fPointer = new Char_t[fNdata];
         }
         fValue = *fPointer;
      } else {
         // -- The data member is fixed size.
         // FIXME: What about fPointer???
         fValue = (char*) addr;
      }
   } else {
      // -- We must create the value buffer ourselves.
      // Note: We are using the size calculated by ResetAddress().
      fValue = new char[fNdata];
      // FIXME: Why initialize at all?
      fValue[0] = 0;
   }
}

<|endoftext|>


<commit_before>/*
 * This file is part of Peli - universal JSON interaction library
 * Copyright (C) 2014  Alexey Chernov <4ernov@gmail.com>
 *
 * Peli 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 3 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, see <http://www.gnu.org/licenses/>.
 *
 */

#include <sstream>
#include <iostream>

#include "peli/json/value.h"

using namespace std;

using namespace peli;

namespace
{
	template<class ExceptionType> bool has_thrown_on(const string& text)
	{
		bool thrown { };

		istringstream is(text);
		json::value v;

		try
		{
			is >> v;
		}
		catch (const ExceptionType&)
		{
			thrown = true;
		}

		return thrown;
	}
}

int check()
{
	const string str1 = "   [\n\tnull   ]\r\n  ";
	const wstring str2 = L"[  \r\tnull   ]\n\t  \n  \n\r  ";

	istringstream is1(str1);
	json::value v1;
	is1 >> v1;

	wistringstream is2(str2);
	json::wvalue v2;
	is2 >> v2;

	const json::array& obj1(get<json::array>(v1));
	const json::warray& obj2(get<json::warray>(v2));
	json::array ch1 { json::value() };
	json::warray ch2 { json::wvalue() };

	if (obj1 != ch1)
		return -1;

	if (obj2 != ch2)
		return -2;

	if (!obj1[0].null())
		return -3;

	return 0;
}

int check_typos()
{
	if (!has_thrown_on<invalid_argument>("nil"))
		return -4;

	if (!has_thrown_on<invalid_argument>("nuul"))
		return -5;

	if (!has_thrown_on<invalid_argument>("nul"))
		return -6;

	return 0;
}

int main(int, char**)
{
	if (const auto r = check())
	{
		return r;
	}

	if (const auto r = check_typos())
	{
		return r;
	}

	return 0;
}
<commit_msg>Positive return codes for null parsing test<commit_after>/*
 * This file is part of Peli - universal JSON interaction library
 * Copyright (C) 2014  Alexey Chernov <4ernov@gmail.com>
 *
 * Peli 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 3 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, see <http://www.gnu.org/licenses/>.
 *
 */

#include <sstream>
#include <iostream>

#include "peli/json/value.h"

using namespace std;

using namespace peli;

namespace
{
	template<class ExceptionType> bool has_thrown_on(const string& text)
	{
		bool thrown { };

		istringstream is(text);
		json::value v;

		try
		{
			is >> v;
		}
		catch (const ExceptionType&)
		{
			thrown = true;
		}

		return thrown;
	}
}

int check()
{
	const string str1 = "   [\n\tnull   ]\r\n  ";
	const wstring str2 = L"[  \r\tnull   ]\n\t  \n  \n\r  ";

	istringstream is1(str1);
	json::value v1;
	is1 >> v1;

	wistringstream is2(str2);
	json::wvalue v2;
	is2 >> v2;

	const json::array& obj1(get<json::array>(v1));
	const json::warray& obj2(get<json::warray>(v2));
	json::array ch1 { json::value() };
	json::warray ch2 { json::wvalue() };

	if (obj1 != ch1)
		return 1;

	if (obj2 != ch2)
		return 2;

	if (!obj1[0].null())
		return 3;

	return 0;
}

int check_typos()
{
	if (!has_thrown_on<invalid_argument>("nil"))
		return 4;

	if (!has_thrown_on<invalid_argument>("nuul"))
		return 5;

	if (!has_thrown_on<invalid_argument>("nul"))
		return 6;

	return 0;
}

int main(int, char**)
{
	if (const auto r = check())
	{
		return r;
	}

	if (const auto r = check_typos())
	{
		return r;
	}

	return 0;
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "ClientAuthentication.h"

/* system implementation headers */
#include <string>
#include <assert.h>
#ifdef HAVE_KRB5
#include <com_err.h>
#endif

#ifdef HAVE_KRB5
krb5_context      ClientAuthentication::context      = NULL;
krb5_ccache       ClientAuthentication::cc           = NULL;
krb5_auth_context ClientAuthentication::auth_context = NULL;
krb5_data         ClientAuthentication::packet;
krb5_data         ClientAuthentication::inbuf;
krb5_creds        ClientAuthentication::creds;
krb5_creds       *ClientAuthentication::new_creds;
krb5_principal    ClientAuthentication::client;
krb5_principal    ClientAuthentication::server;
char*             ClientAuthentication::principalName;
#endif
bool              ClientAuthentication::authentication = false;

void ClientAuthentication::init()
{
#ifdef HAVE_KRB5
  assert(context == NULL);
  assert(cc == NULL);
  krb5_error_code retval;
  // Initializing kerberos library
  if ((retval = krb5_init_context(&context)))
    com_err("bzflag:", retval, "while initializing krb5");
  // Getting credential cache
  if (context && (retval = krb5_cc_default(context, &cc)))
    com_err("bzflag:", retval, "getting credentials cache");
  if (cc && (retval = krb5_cc_get_principal(context, cc, &client)))
    com_err("bzflag:", retval, "getting principal name");
  if (!retval && (retval = krb5_unparse_name(context, client, &principalName)))
    com_err("bzflag:", retval, "unparsing principal name");
  if (context && (retval = krb5_parse_name(context,
					   "krbtgt/BZFLAG.ORG@BZFLAG.ORG",
					   &server)))
    com_err("bzflag:", retval, "setting up tgt server name");
  authentication = (retval == 0);
#endif
}

#ifdef HAVE_KRB5
void ClientAuthentication::sendCredential(ServerLink &serverLink)
#else
void ClientAuthentication::sendCredential(ServerLink&)
#endif // HAVE_KRB5
{
  if (!authentication)
    return;
#ifdef HAVE_KRB5
  assert(context != NULL);
  assert(cc != NULL);
  assert(principalName != NULL);

  krb5_error_code retval;
  /* Get credentials for server */
  memset((char*)&creds, 0, sizeof(creds));
  memcpy(&creds.client, &client, sizeof(client));
  memcpy(&creds.server, &server, sizeof(server));
  /* Get credentials for server */
  if ((retval = krb5_get_credentials(context, KRB5_GC_CACHED, cc, &creds,
				     &new_creds)))
    com_err("bzflag:", retval, "getting TGT");
  if (!retval) {
    serverLink.sendKerberosTicket(principalName, &new_creds->ticket);
  }
#endif
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>-debug is needed to print krb errors<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "ClientAuthentication.h"

/* system implementation headers */
#include <string>
#include <assert.h>
#ifdef HAVE_KRB5
#include <com_err.h>
#define err(x,y,z) if (debugLevel >= 1) com_err(x,y,z)
#endif

#ifdef HAVE_KRB5
krb5_context      ClientAuthentication::context      = NULL;
krb5_ccache       ClientAuthentication::cc           = NULL;
krb5_auth_context ClientAuthentication::auth_context = NULL;
krb5_data         ClientAuthentication::packet;
krb5_data         ClientAuthentication::inbuf;
krb5_creds        ClientAuthentication::creds;
krb5_creds       *ClientAuthentication::new_creds;
krb5_principal    ClientAuthentication::client;
krb5_principal    ClientAuthentication::server;
char*             ClientAuthentication::principalName;
#endif
bool              ClientAuthentication::authentication = false;

void ClientAuthentication::init()
{
#ifdef HAVE_KRB5
  assert(context == NULL);
  assert(cc == NULL);
  krb5_error_code retval;
  // Initializing kerberos library
  if ((retval = krb5_init_context(&context)))
    err("bzflag:", retval, "while initializing krb5");
  // Getting credential cache
  if (context && (retval = krb5_cc_default(context, &cc)))
    err("bzflag:", retval, "getting credentials cache");
  if (cc && (retval = krb5_cc_get_principal(context, cc, &client)))
    err("bzflag:", retval, "getting principal name");
  if (!retval && (retval = krb5_unparse_name(context, client, &principalName)))
    err("bzflag:", retval, "unparsing principal name");
  if (context && (retval = krb5_parse_name(context,
					   "krbtgt/BZFLAG.ORG@BZFLAG.ORG",
					   &server)))
    err("bzflag:", retval, "setting up tgt server name");
  authentication = (retval == 0);
#endif
}

#ifdef HAVE_KRB5
void ClientAuthentication::sendCredential(ServerLink &serverLink)
#else
void ClientAuthentication::sendCredential(ServerLink&)
#endif // HAVE_KRB5
{
  if (!authentication)
    return;
#ifdef HAVE_KRB5
  assert(context != NULL);
  assert(cc != NULL);
  assert(principalName != NULL);

  krb5_error_code retval;
  /* Get credentials for server */
  memset((char*)&creds, 0, sizeof(creds));
  memcpy(&creds.client, &client, sizeof(client));
  memcpy(&creds.server, &server, sizeof(server));
  /* Get credentials for server */
  if ((retval = krb5_get_credentials(context, KRB5_GC_CACHED, cc, &creds,
				     &new_creds)))
    err("bzflag:", retval, "getting TGT");
  if (!retval) {
    serverLink.sendKerberosTicket(principalName, &new_creds->ticket);
  }
#endif
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <chartsql/expressions/boolean.h>
#include <fnord/exception.h>

namespace csql {
namespace expressions {

void eqExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for eq. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() == rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() == rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() == rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() == rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void neqExpr(int argc, SValue* argv, SValue* out) {
  SValue ret;
  eqExpr(argc, argv, &ret);
  *out = SValue(!ret.getValue<bool>());
}

void andExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for and. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->getType()) {
    case SValue::T_BOOL:
      switch(rhs->getType()) {
        case SValue::T_BOOL:
          *out = SValue(lhs->getBool() && rhs->getBool());
          return;
        default:
          break;
      }
    default:
      break;
  }

  RAISE(kRuntimeError, "can't AND %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void orExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for or. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->getType()) {
    case SValue::T_BOOL:
      switch(rhs->getType()) {
        case SValue::T_BOOL:
          *out = SValue(lhs->getBool() || rhs->getBool());
          return;
        default:
          break;
      }
    default:
      break;
  }

  RAISE(kRuntimeError, "can't OR %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void negExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 1) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for neg. expected: 1, got: %i", argc);
  }

  SValue* val = argv;

  switch(val->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
      *out = SValue(val->getInteger() * -1);
      return;
    case SValue::T_FLOAT:
      *out = SValue(val->getFloat() * -1.0f);
      return;
    case SValue::T_BOOL:
      *out = SValue(!val->getBool());
      return;
    default:
      break;
  }

  RAISE(kRuntimeError, "can't negate %s",
      val->getTypeName());
}

void ltExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for ltExpr. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() < rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() < rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() < rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() < rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void lteExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for lteExpr. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() <= rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() <= rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() <= rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() <= rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void gtExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for gtExpr. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() > rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() > rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() > rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() > rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void gteExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for gteExpr. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() >= rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() >= rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() >= rhs->getFloat());
          return;
        default:
          break;
      }
      break;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() >= rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

}
}
<commit_msg>handle NULL in boolean expressions<commit_after>/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <chartsql/expressions/boolean.h>
#include <fnord/exception.h>

namespace csql {
namespace expressions {

void eqExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for eq. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() == rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() == rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() == rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_NULL:
      *out = SValue(SValue::BoolType(false));
      return;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() == rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void neqExpr(int argc, SValue* argv, SValue* out) {
  SValue ret;
  eqExpr(argc, argv, &ret);
  *out = SValue(!ret.getValue<bool>());
}

void andExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for and. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->getType()) {
    case SValue::T_BOOL:
      switch(rhs->getType()) {
        case SValue::T_BOOL:
          *out = SValue(lhs->getBool() && rhs->getBool());
          return;
        default:
          break;
      }
    default:
      break;
  }

  RAISE(kRuntimeError, "can't AND %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void orExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for or. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->getType()) {
    case SValue::T_BOOL:
      switch(rhs->getType()) {
        case SValue::T_BOOL:
          *out = SValue(lhs->getBool() || rhs->getBool());
          return;
        default:
          break;
      }
    default:
      break;
  }

  RAISE(kRuntimeError, "can't OR %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void negExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 1) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for neg. expected: 1, got: %i", argc);
  }

  SValue* val = argv;

  switch(val->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
      *out = SValue(val->getInteger() * -1);
      return;
    case SValue::T_FLOAT:
      *out = SValue(val->getFloat() * -1.0f);
      return;
    case SValue::T_BOOL:
      *out = SValue(!val->getBool());
      return;
    case SValue::T_NULL:
      *out = SValue();
      return;
    default:
      break;
  }

  RAISE(kRuntimeError, "can't negate %s",
      val->getTypeName());
}

void ltExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for ltExpr. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() < rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() < rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() < rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_NULL:
      *out = SValue(SValue::BoolType(false));
      return;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() < rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void lteExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for lteExpr. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() <= rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() <= rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() <= rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_NULL:
      *out = SValue(SValue::BoolType(false));
      return;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() <= rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void gtExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for gtExpr. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() > rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() > rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() > rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_NULL:
      *out = SValue(SValue::BoolType(false));
      return;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() > rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

void gteExpr(int argc, SValue* argv, SValue* out) {
  if (argc != 2) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for gteExpr. expected: 2, got: %i", argc);
  }

  SValue* lhs = argv;
  SValue* rhs = argv + 1;

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() >= rhs->getInteger());
          return;
        case SValue::T_FLOAT:
          *out = SValue(lhs->getFloat() >= rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_FLOAT:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() >= rhs->getFloat());
          return;
        case SValue::T_NULL:
          *out = SValue(SValue::BoolType(false));
          return;
        default:
          break;
      }
      break;
    case SValue::T_NULL:
      *out = SValue(SValue::BoolType(false));
      return;
    default:
      break;
  }

  if (lhs->getType() == SValue::T_STRING ||
      rhs->getType() == SValue::T_STRING) {
    *out = SValue(lhs->toString() >= rhs->toString());
    return;
  }

  RAISE(kRuntimeError, "can't compare %s with %s",
      lhs->getTypeName(),
      rhs->getTypeName());
}

}
}
<|endoftext|>


<commit_before><commit_msg>improve assert messages<commit_after><|endoftext|>