<commit_before>#include <string.h>

#include "transport.h"
#include "core.h"
#include "network.h"
#include "log.h"

using namespace std;

// FIXME: Rework netCreateBuf and netExPacket. We don't need to
// duplicate the sender/receiver info the packet. This should be known
// by the transport layer and given to us. We also should be more
// intelligent about the time stamps, right now the method is very
// ugly.

Network::Network(Core *core)
      : _core(core)
{
   LOG_ASSERT_ERROR(sizeof(g_type_to_static_network_map) / sizeof(EStaticNetwork) == NUM_PACKET_TYPES,
                    "Static network type map has incorrect number of entries.");

   _numMod = Config::getSingleton()->getTotalCores();
   _tid = _core->getId();

   _transport = Transport::getSingleton()->createNode(_core->getId());

   _callbacks = new NetworkCallback [NUM_PACKET_TYPES];
   _callbackObjs = new void* [NUM_PACKET_TYPES];
   for (SInt32 i = 0; i < NUM_PACKET_TYPES; i++)
      _callbacks[i] = NULL;

   UInt32 modelTypes[NUM_STATIC_NETWORKS];
   Config::getSingleton()->getNetworkModels(modelTypes);

   for (SInt32 i = 0; i < NUM_STATIC_NETWORKS; i++)
      _models[i] = NetworkModel::createModel(this, modelTypes[i], (EStaticNetwork)i);

   LOG_PRINT("Initialized.");
}

Network::~Network()
{
   for (SInt32 i = 0; i < NUM_STATIC_NETWORKS; i++)
      delete _models[i];

   delete [] _callbackObjs;
   delete [] _callbacks;

   delete _transport;

   LOG_PRINT("Destroyed.");
}

void Network::registerCallback(PacketType type, NetworkCallback callback, void *obj)
{
   assert((UInt32)type < NUM_PACKET_TYPES);
   _callbacks[type] = callback;
   _callbackObjs[type] = obj;
}

void Network::unregisterCallback(PacketType type)
{
   assert((UInt32)type < NUM_PACKET_TYPES);
   _callbacks[type] = NULL;
}

void Network::outputSummary(std::ostream &out) const
{
   out << "Network summary:\n";
   for (UInt32 i = 0; i < NUM_STATIC_NETWORKS; i++)
   {
      out << "  Network model " << i << ":\n";
      _models[i]->outputSummary(out);
   }
}

// Polling function that performs background activities, such as
// pulling from the physical transport layer and routing packets to
// the appropriate queues.

void Network::netPullFromTransport()
{
   do
   {
      LOG_PRINT("Entering netPullFromTransport");

      NetPacket packet(_transport->recv());

      LOG_PRINT("Pull packet : type %i, from %i, time %llu", (SInt32)packet.type, packet.sender, packet.time);
      assert(0 <= packet.sender && packet.sender < _numMod);
      LOG_ASSERT_ERROR(0 <= packet.type && packet.type < NUM_PACKET_TYPES, "Packet type: %d not between 0 and %d", packet.type, NUM_PACKET_TYPES);

      // was this packet sent to us, or should it just be forwarded?
      if (packet.receiver != _core->getId())
      {
         // Disable this feature now. None of the network models use it
         LOG_PRINT("Forwarding packet : type %i, from %i, to %i, core_id %i, time %llu.",
               (SInt32)packet.type, packet.sender, packet.receiver, _core->getId(), packet.time);
         forwardPacket(packet);

         // if this isn't a broadcast message, then we shouldn't process it further
         if (packet.receiver != NetPacket::BROADCAST)
            continue;
      }

      // asynchronous I/O support
      NetworkCallback callback = _callbacks[packet.type];

      if (callback != NULL)
      {
         LOG_PRINT("Executing callback on packet : type %i, from %i, to %i, core_id %i, time %llu",
               (SInt32)packet.type, packet.sender, packet.receiver, _core->getId(), packet.time);
         assert(0 <= packet.sender && packet.sender < _numMod);
         assert(0 <= packet.type && packet.type < NUM_PACKET_TYPES);

         callback(_callbackObjs[packet.type], packet);

         if (packet.length > 0)
            delete [] (Byte*) packet.data;
      }

      // synchronous I/O support
      else
      {
         LOG_PRINT("Enqueuing packet : type %i, from %i, to %i, core_id %i, time %llu.",
               (SInt32)packet.type, packet.sender, packet.receiver, _core->getId(), packet.time);
         _netQueueLock.acquire();
         _netQueue.push_back(packet);
         _netQueueLock.release();
         _netQueueCond.broadcast();
      }
   }
   while (_transport->query());
}

// FIXME: Can forwardPacket be subsumed by netSend?

void Network::forwardPacket(const NetPacket &packet)
{
   netSend(packet);
}

SInt32 Network::netSend(const NetPacket& packet)
{
   assert(packet.type >= 0 && packet.type < NUM_PACKET_TYPES);

   NetworkModel *model = _models[g_type_to_static_network_map[packet.type]];

   vector<NetworkModel::Hop> hopVec;
   model->routePacket(packet, hopVec);

   Byte *buffer = packet.makeBuffer();

   for (UInt32 i = 0; i < hopVec.size(); i++)
   {
      LOG_PRINT("Send packet : type %i, from %i, to %i, next_hop %i, core_id %i, time %llu",
            (SInt32) packet.type, packet.sender, hopVec[i].final_dest, hopVec[i].next_dest, _core->getId(), hopVec[i].time);
      LOG_ASSERT_ERROR(hopVec[i].time >= packet.time, "hopVec[%d].time(%llu) < packet.time(%llu)", i, hopVec[i].time, packet.time);

      NetPacket* buff_pkt = (NetPacket*) buffer;
      buff_pkt->time = hopVec[i].time;
      buff_pkt->receiver = hopVec[i].final_dest;

      _transport->send(hopVec[i].next_dest, buffer, packet.bufferSize());

      LOG_PRINT("Sent packet");
   }

   delete [] buffer;

   return packet.length;
}

// Stupid helper class to eliminate special cases for empty
// sender/type vectors in a NetMatch
class NetRecvIterator
{
   public:
      NetRecvIterator(UInt32 i)
            : _mode(INT)
            , _max(i)
            , _i(0)
      {
      }
      NetRecvIterator(const std::vector<SInt32> &v)
            : _mode(SENDER_VECTOR)
            , _senders(&v)
            , _i(0)
      {
      }
      NetRecvIterator(const std::vector<PacketType> &v)
            : _mode(TYPE_VECTOR)
            , _types(&v)
            , _i(0)
      {
      }

      inline UInt32 get()
      {
         switch (_mode)
         {
         case INT:
            return _i;
         case SENDER_VECTOR:
            return (UInt32)_senders->at(_i);
         case TYPE_VECTOR:
            return (UInt32)_types->at(_i);
         default:
            assert(false);
            return (UInt32)-1;
         };
      }

      inline Boolean done()
      {
         switch (_mode)
         {
         case INT:
            return _i >= _max;
         case SENDER_VECTOR:
            return _i >= _senders->size();
         case TYPE_VECTOR:
            return _i >= _types->size();
         default:
            assert(false);
            return true;
         };
      }

      inline void next()
      {
         ++_i;
      }

      inline void reset()
      {
         _i = 0;
      }

   private:
      enum
      {
         INT, SENDER_VECTOR, TYPE_VECTOR
      } _mode;

      union
      {
         UInt32 _max;
         const std::vector<SInt32> *_senders;
         const std::vector<PacketType> *_types;
      };

      UInt32 _i;
};

NetPacket Network::netRecv(const NetMatch &match)
{
   LOG_PRINT("Entering netRecv.");

   // Track via iterator to minimize copying
   NetQueue::iterator itr;
   Boolean found;

   found = false;

   NetRecvIterator sender = match.senders.empty()
                            ? NetRecvIterator(_numMod)
                            : NetRecvIterator(match.senders);

   NetRecvIterator type = match.types.empty()
                          ? NetRecvIterator((UInt32)NUM_PACKET_TYPES)
                          : NetRecvIterator(match.types);

   LOG_ASSERT_ERROR(_core && _core->getPerformanceModel(),
                    "Core and/or performance model not initialized.");
   UInt64 start_time = _core->getPerformanceModel()->getCycleCount();

   _netQueueLock.acquire();

   while (!found)
   {
      itr = _netQueue.end();

      // check every entry in the queue
      for (NetQueue::iterator i = _netQueue.begin();
            i != _netQueue.end();
            i++)
      {
         // only find packets that match
         for (sender.reset(); !sender.done(); sender.next())
         {
            if (i->sender != (SInt32)sender.get())
               continue;

            for (type.reset(); !type.done(); type.next())
            {
               if (i->type != (PacketType)type.get())
                  continue;

               found = true;

               // find the earliest packet
               if (itr == _netQueue.end() ||
                   itr->time > i->time)
               {
                  itr = i;
               }
            }
         }
      }

      // go to sleep until a packet arrives if none have been found
      if (!found)
      {
         _netQueueCond.wait(_netQueueLock);
      }
   }

   assert(found == true && itr != _netQueue.end());
   assert(0 <= itr->sender && itr->sender < _numMod);
   assert(0 <= itr->type && itr->type < NUM_PACKET_TYPES);
   assert((itr->receiver == _core->getId()) || (itr->receiver == NetPacket::BROADCAST));

   // Copy result
   NetPacket packet = *itr;
   _netQueue.erase(itr);
   _netQueueLock.release();

   LOG_PRINT("packet.time(%llu), start_time(%llu)", packet.time, start_time);

   if (packet.time > start_time)
   {
      LOG_PRINT("Queueing RecvInstruction(%llu)", packet.time - start_time);
      Instruction *i = new RecvInstruction(packet.time - start_time);
      _core->getPerformanceModel()->queueDynamicInstruction(i);
   }

   LOG_PRINT("Exiting netRecv : type %i, from %i", (SInt32)packet.type, packet.sender);

   return packet;
}

// -- Wrappers

SInt32 Network::netSend(SInt32 dest, PacketType type, const void *buf, UInt32 len)
{
   NetPacket packet;
   assert(_core && _core->getPerformanceModel());
   packet.time = _core->getPerformanceModel()->getCycleCount();
   packet.sender = _core->getId();
   packet.receiver = dest;
   packet.length = len;
   packet.type = type;
   packet.data = buf;

   return netSend(packet);
}

SInt32 Network::netBroadcast(PacketType type, const void *buf, UInt32 len)
{
   return netSend(NetPacket::BROADCAST, type, buf, len);
}

NetPacket Network::netRecv(SInt32 src, PacketType type)
{
   NetMatch match;
   match.senders.push_back(src);
   match.types.push_back(type);
   return netRecv(match);
}

NetPacket Network::netRecvFrom(SInt32 src)
{
   NetMatch match;
   match.senders.push_back(src);
   return netRecv(match);
}

NetPacket Network::netRecvType(PacketType type)
{
   NetMatch match;
   match.types.push_back(type);
   return netRecv(match);
}

void Network::enableModels()
{
   for (int i = 0; i < NUM_STATIC_NETWORKS; i++)
   {
      _models[i]->enable();
   }
}

void Network::disableModels()
{
   for (int i = 0; i < NUM_STATIC_NETWORKS; i++)
   {
      _models[i]->disable();
   }
}

// -- NetPacket

NetPacket::NetPacket()
   : time(0)
   , type(INVALID)
   , sender(INVALID_CORE_ID)
   , receiver(INVALID_CORE_ID)
   , length(0)
   , data(0)
{
}

NetPacket::NetPacket(UInt64 t, PacketType ty, SInt32 s,
                     SInt32 r, UInt32 l, const void *d)
   : time(t)
   , type(ty)
   , sender(s)
   , receiver(r)
   , length(l)
   , data(d)
{
}

NetPacket::NetPacket(Byte *buffer)
{
   memcpy(this, buffer, sizeof(*this));

   // LOG_ASSERT_ERROR(length > 0, "type(%u), sender(%i), receiver(%i), length(%u)", type, sender, receiver, length);
   if (length > 0)
   {
      Byte* data_buffer = new Byte[length];
      memcpy(data_buffer, buffer + sizeof(*this), length);
      data = data_buffer;
   }

   delete [] buffer;
}

// This implementation is slightly wasteful because there is no need
// to copy the const void* value in the NetPacket when length == 0,
// but I don't see this as a major issue.
UInt32 NetPacket::bufferSize() const
{
   return (sizeof(*this) + length);
}

Byte* NetPacket::makeBuffer() const
{
   UInt32 size = bufferSize();
   assert(size >= sizeof(NetPacket));

   Byte *buffer = new Byte[size];

   memcpy(buffer, this, sizeof(*this));
   memcpy(buffer + sizeof(*this), data, length);

   return buffer;
}
<commit_msg>[network] Fixed a memory leak started while forwarding packets in the network<commit_after>#include <string.h>

#include "transport.h"
#include "core.h"
#include "network.h"
#include "log.h"

using namespace std;

// FIXME: Rework netCreateBuf and netExPacket. We don't need to
// duplicate the sender/receiver info the packet. This should be known
// by the transport layer and given to us. We also should be more
// intelligent about the time stamps, right now the method is very
// ugly.

Network::Network(Core *core)
      : _core(core)
{
   LOG_ASSERT_ERROR(sizeof(g_type_to_static_network_map) / sizeof(EStaticNetwork) == NUM_PACKET_TYPES,
                    "Static network type map has incorrect number of entries.");

   _numMod = Config::getSingleton()->getTotalCores();
   _tid = _core->getId();

   _transport = Transport::getSingleton()->createNode(_core->getId());

   _callbacks = new NetworkCallback [NUM_PACKET_TYPES];
   _callbackObjs = new void* [NUM_PACKET_TYPES];
   for (SInt32 i = 0; i < NUM_PACKET_TYPES; i++)
      _callbacks[i] = NULL;

   UInt32 modelTypes[NUM_STATIC_NETWORKS];
   Config::getSingleton()->getNetworkModels(modelTypes);

   for (SInt32 i = 0; i < NUM_STATIC_NETWORKS; i++)
      _models[i] = NetworkModel::createModel(this, modelTypes[i], (EStaticNetwork)i);

   LOG_PRINT("Initialized.");
}

Network::~Network()
{
   for (SInt32 i = 0; i < NUM_STATIC_NETWORKS; i++)
      delete _models[i];

   delete [] _callbackObjs;
   delete [] _callbacks;

   delete _transport;

   LOG_PRINT("Destroyed.");
}

void Network::registerCallback(PacketType type, NetworkCallback callback, void *obj)
{
   assert((UInt32)type < NUM_PACKET_TYPES);
   _callbacks[type] = callback;
   _callbackObjs[type] = obj;
}

void Network::unregisterCallback(PacketType type)
{
   assert((UInt32)type < NUM_PACKET_TYPES);
   _callbacks[type] = NULL;
}

void Network::outputSummary(std::ostream &out) const
{
   out << "Network summary:\n";
   for (UInt32 i = 0; i < NUM_STATIC_NETWORKS; i++)
   {
      out << "  Network model " << i << ":\n";
      _models[i]->outputSummary(out);
   }
}

// Polling function that performs background activities, such as
// pulling from the physical transport layer and routing packets to
// the appropriate queues.

void Network::netPullFromTransport()
{
   do
   {
      LOG_PRINT("Entering netPullFromTransport");

      NetPacket packet(_transport->recv());

      LOG_PRINT("Pull packet : type %i, from %i, time %llu", (SInt32)packet.type, packet.sender, packet.time);
      assert(0 <= packet.sender && packet.sender < _numMod);
      LOG_ASSERT_ERROR(0 <= packet.type && packet.type < NUM_PACKET_TYPES, "Packet type: %d not between 0 and %d", packet.type, NUM_PACKET_TYPES);

      // was this packet sent to us, or should it just be forwarded?
      if (packet.receiver != _core->getId())
      {
         // Disable this feature now. None of the network models use it
         LOG_PRINT("Forwarding packet : type %i, from %i, to %i, core_id %i, time %llu.",
               (SInt32)packet.type, packet.sender, packet.receiver, _core->getId(), packet.time);
         forwardPacket(packet);

         // if this isn't a broadcast message, then we shouldn't process it further
         if (packet.receiver != NetPacket::BROADCAST)
         {
            if (packet.length > 0)
               delete [] (Byte*) packet.data;
            continue;
         }
      }

      // asynchronous I/O support
      NetworkCallback callback = _callbacks[packet.type];

      if (callback != NULL)
      {
         LOG_PRINT("Executing callback on packet : type %i, from %i, to %i, core_id %i, time %llu",
               (SInt32)packet.type, packet.sender, packet.receiver, _core->getId(), packet.time);
         assert(0 <= packet.sender && packet.sender < _numMod);
         assert(0 <= packet.type && packet.type < NUM_PACKET_TYPES);

         callback(_callbackObjs[packet.type], packet);

         if (packet.length > 0)
            delete [] (Byte*) packet.data;
      }

      // synchronous I/O support
      else
      {
         LOG_PRINT("Enqueuing packet : type %i, from %i, to %i, core_id %i, time %llu.",
               (SInt32)packet.type, packet.sender, packet.receiver, _core->getId(), packet.time);
         _netQueueLock.acquire();
         _netQueue.push_back(packet);
         _netQueueLock.release();
         _netQueueCond.broadcast();
      }
   }
   while (_transport->query());
}

// FIXME: Can forwardPacket be subsumed by netSend?

void Network::forwardPacket(const NetPacket &packet)
{
   netSend(packet);
}

SInt32 Network::netSend(const NetPacket& packet)
{
   assert(packet.type >= 0 && packet.type < NUM_PACKET_TYPES);

   NetworkModel *model = _models[g_type_to_static_network_map[packet.type]];

   vector<NetworkModel::Hop> hopVec;
   model->routePacket(packet, hopVec);

   Byte *buffer = packet.makeBuffer();

   for (UInt32 i = 0; i < hopVec.size(); i++)
   {
      LOG_PRINT("Send packet : type %i, from %i, to %i, next_hop %i, core_id %i, time %llu",
            (SInt32) packet.type, packet.sender, hopVec[i].final_dest, hopVec[i].next_dest, _core->getId(), hopVec[i].time);
      LOG_ASSERT_ERROR(hopVec[i].time >= packet.time, "hopVec[%d].time(%llu) < packet.time(%llu)", i, hopVec[i].time, packet.time);

      NetPacket* buff_pkt = (NetPacket*) buffer;
      buff_pkt->time = hopVec[i].time;
      buff_pkt->receiver = hopVec[i].final_dest;

      _transport->send(hopVec[i].next_dest, buffer, packet.bufferSize());

      LOG_PRINT("Sent packet");
   }

   delete [] buffer;

   return packet.length;
}

// Stupid helper class to eliminate special cases for empty
// sender/type vectors in a NetMatch
class NetRecvIterator
{
   public:
      NetRecvIterator(UInt32 i)
            : _mode(INT)
            , _max(i)
            , _i(0)
      {
      }
      NetRecvIterator(const std::vector<SInt32> &v)
            : _mode(SENDER_VECTOR)
            , _senders(&v)
            , _i(0)
      {
      }
      NetRecvIterator(const std::vector<PacketType> &v)
            : _mode(TYPE_VECTOR)
            , _types(&v)
            , _i(0)
      {
      }

      inline UInt32 get()
      {
         switch (_mode)
         {
         case INT:
            return _i;
         case SENDER_VECTOR:
            return (UInt32)_senders->at(_i);
         case TYPE_VECTOR:
            return (UInt32)_types->at(_i);
         default:
            assert(false);
            return (UInt32)-1;
         };
      }

      inline Boolean done()
      {
         switch (_mode)
         {
         case INT:
            return _i >= _max;
         case SENDER_VECTOR:
            return _i >= _senders->size();
         case TYPE_VECTOR:
            return _i >= _types->size();
         default:
            assert(false);
            return true;
         };
      }

      inline void next()
      {
         ++_i;
      }

      inline void reset()
      {
         _i = 0;
      }

   private:
      enum
      {
         INT, SENDER_VECTOR, TYPE_VECTOR
      } _mode;

      union
      {
         UInt32 _max;
         const std::vector<SInt32> *_senders;
         const std::vector<PacketType> *_types;
      };

      UInt32 _i;
};

NetPacket Network::netRecv(const NetMatch &match)
{
   LOG_PRINT("Entering netRecv.");

   // Track via iterator to minimize copying
   NetQueue::iterator itr;
   Boolean found;

   found = false;

   NetRecvIterator sender = match.senders.empty()
                            ? NetRecvIterator(_numMod)
                            : NetRecvIterator(match.senders);

   NetRecvIterator type = match.types.empty()
                          ? NetRecvIterator((UInt32)NUM_PACKET_TYPES)
                          : NetRecvIterator(match.types);

   LOG_ASSERT_ERROR(_core && _core->getPerformanceModel(),
                    "Core and/or performance model not initialized.");
   UInt64 start_time = _core->getPerformanceModel()->getCycleCount();

   _netQueueLock.acquire();

   while (!found)
   {
      itr = _netQueue.end();

      // check every entry in the queue
      for (NetQueue::iterator i = _netQueue.begin();
            i != _netQueue.end();
            i++)
      {
         // only find packets that match
         for (sender.reset(); !sender.done(); sender.next())
         {
            if (i->sender != (SInt32)sender.get())
               continue;

            for (type.reset(); !type.done(); type.next())
            {
               if (i->type != (PacketType)type.get())
                  continue;

               found = true;

               // find the earliest packet
               if (itr == _netQueue.end() ||
                   itr->time > i->time)
               {
                  itr = i;
               }
            }
         }
      }

      // go to sleep until a packet arrives if none have been found
      if (!found)
      {
         _netQueueCond.wait(_netQueueLock);
      }
   }

   assert(found == true && itr != _netQueue.end());
   assert(0 <= itr->sender && itr->sender < _numMod);
   assert(0 <= itr->type && itr->type < NUM_PACKET_TYPES);
   assert((itr->receiver == _core->getId()) || (itr->receiver == NetPacket::BROADCAST));

   // Copy result
   NetPacket packet = *itr;
   _netQueue.erase(itr);
   _netQueueLock.release();

   LOG_PRINT("packet.time(%llu), start_time(%llu)", packet.time, start_time);

   if (packet.time > start_time)
   {
      LOG_PRINT("Queueing RecvInstruction(%llu)", packet.time - start_time);
      Instruction *i = new RecvInstruction(packet.time - start_time);
      _core->getPerformanceModel()->queueDynamicInstruction(i);
   }

   LOG_PRINT("Exiting netRecv : type %i, from %i", (SInt32)packet.type, packet.sender);

   return packet;
}

// -- Wrappers

SInt32 Network::netSend(SInt32 dest, PacketType type, const void *buf, UInt32 len)
{
   NetPacket packet;
   assert(_core && _core->getPerformanceModel());
   packet.time = _core->getPerformanceModel()->getCycleCount();
   packet.sender = _core->getId();
   packet.receiver = dest;
   packet.length = len;
   packet.type = type;
   packet.data = buf;

   return netSend(packet);
}

SInt32 Network::netBroadcast(PacketType type, const void *buf, UInt32 len)
{
   return netSend(NetPacket::BROADCAST, type, buf, len);
}

NetPacket Network::netRecv(SInt32 src, PacketType type)
{
   NetMatch match;
   match.senders.push_back(src);
   match.types.push_back(type);
   return netRecv(match);
}

NetPacket Network::netRecvFrom(SInt32 src)
{
   NetMatch match;
   match.senders.push_back(src);
   return netRecv(match);
}

NetPacket Network::netRecvType(PacketType type)
{
   NetMatch match;
   match.types.push_back(type);
   return netRecv(match);
}

void Network::enableModels()
{
   for (int i = 0; i < NUM_STATIC_NETWORKS; i++)
   {
      _models[i]->enable();
   }
}

void Network::disableModels()
{
   for (int i = 0; i < NUM_STATIC_NETWORKS; i++)
   {
      _models[i]->disable();
   }
}

// -- NetPacket

NetPacket::NetPacket()
   : time(0)
   , type(INVALID)
   , sender(INVALID_CORE_ID)
   , receiver(INVALID_CORE_ID)
   , length(0)
   , data(0)
{
}

NetPacket::NetPacket(UInt64 t, PacketType ty, SInt32 s,
                     SInt32 r, UInt32 l, const void *d)
   : time(t)
   , type(ty)
   , sender(s)
   , receiver(r)
   , length(l)
   , data(d)
{
}

NetPacket::NetPacket(Byte *buffer)
{
   memcpy(this, buffer, sizeof(*this));

   // LOG_ASSERT_ERROR(length > 0, "type(%u), sender(%i), receiver(%i), length(%u)", type, sender, receiver, length);
   if (length > 0)
   {
      Byte* data_buffer = new Byte[length];
      memcpy(data_buffer, buffer + sizeof(*this), length);
      data = data_buffer;
   }

   delete [] buffer;
}

// This implementation is slightly wasteful because there is no need
// to copy the const void* value in the NetPacket when length == 0,
// but I don't see this as a major issue.
UInt32 NetPacket::bufferSize() const
{
   return (sizeof(*this) + length);
}

Byte* NetPacket::makeBuffer() const
{
   UInt32 size = bufferSize();
   assert(size >= sizeof(NetPacket));

   Byte *buffer = new Byte[size];

   memcpy(buffer, this, sizeof(*this));
   memcpy(buffer + sizeof(*this), data, length);

   return buffer;
}
<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#define _POSIX_SOURCE
#include <sys/types.h>
#include <stdlib.h>

void * operator new(size_t size)
{
	return (void *)malloc(size);
}

void operator delete( void *to_free )
{
	if( to_free ) {
		(void)free( to_free );
	}
}

#if defined( __GNUC__ )
#	if (__GNUG__== 2 && (__GNUC_MINOR__ == 6 || __GNUC_MINOR__ == 7))
		extern "C" {
			void *__builtin_new( size_t );
			void __builtin_delete( void * );
			void *
			__builtin_vec_new (size_t sz)
			{
				return __builtin_new( sz );
			}

			void
			__builtin_vec_delete( void *to_free )
			{
				__builtin_delete( to_free );
			}
		}
#	endif
#endif
<commit_msg>- #include "condor_common.h" - define __pure_virtual() to avoid problems linking our egcs compiled   C++ code with a non-egcs compiled user job<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "condor_common.h"

void * operator new(size_t size)
{
	return (void *)malloc(size);
}

void operator delete( void *to_free )
{
	if( to_free ) {
		(void)free( to_free );
	}
}

#if defined( __GNUC__ )
#	if (__GNUG__== 2 && (__GNUC_MINOR__ == 6 || __GNUC_MINOR__ == 7))
		extern "C" {
			void *__builtin_new( size_t );
			void __builtin_delete( void * );
			void *
			__builtin_vec_new (size_t sz)
			{
				return __builtin_new( sz );
			}

			void
			__builtin_vec_delete( void *to_free )
			{
				__builtin_delete( to_free );
			}
		}
#	endif
#endif

/* This function is called by egcs when a pure virtual method is called.
   Since the user job may not be linking with egcs libraries, we need to
   provide our own version. */

#define MESSAGE "pure virtual method called\n"

extern "C" {
void
__pure_virtual()
{
	write (2, MESSAGE, sizeof (MESSAGE) - 1);
	_exit (1);
}
}
<|endoftext|>


<commit_before>#include <iostream>
#include <tuple>
#include <limits>

namespace ceps{
 namespace serialization{
   namespace basic{
     constexpr unsigned long long inline read_base128_ull(unsigned char* addr, unsigned short max_width = 10)
     {
        unsigned long long r = *((unsigned long long*)addr);
        if ( (r & 0x80) == 0) return r & 0x7f;
        else if ( (r & 0x8000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1);
        else if ( (r & 0x800000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2);
        else if ( (r & 0x80000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) ;
        else if ( (r & 0x8000000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                ((r & 0x7f00000000) >> 4) ;
        else if ( (r & 0x800000000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) ;
        else if ( (r & 0x80000000000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) | ((r & 0x7f000000000000) >> 6);
        else if ( (r & 0x8000000000000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) |
                ((r & 0x7f000000000000) >> 6) | ((r & 0x7f00000000000000) >> 7);
        else if ((*(addr + sizeof(unsigned long long int)) & 0x80) == 0)
          return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                 ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) |
                 ((r & 0x7f000000000000) >> 6) | ((r & 0x7f00000000000000) >> 7) |
                 ((unsigned long long int)(*(addr + sizeof(unsigned long long int)) & 0x7f) << 56);
        return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
               ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) |
               ((r & 0x7f000000000000) >> 6) | ((r & 0x7f00000000000000) >> 7) |
               ((unsigned long long int)(*(addr + sizeof(unsigned long long int)) & 0x7f) << 56)|
               ((unsigned long long int)(*(addr + sizeof(unsigned long long int)+1) & 0x01) << 63);
     }
   }
   unsigned short write_base128(unsigned char* addr, unsigned long long value){
          unsigned short bytes_to_write = 0;
          if (0x8000000000000000 & value){ // => 80 bit representation (64 bit value)
            bytes_to_write = 10;
          }
          else if (0x7f00000000000000 & value){ // => 72 bit representation (63 bit value)
            bytes_to_write = 9;
          }
          else if (0xfe000000000000 & value){ // => 64 bit representation (56 bit value)
            bytes_to_write = 8;
          }
          else if (  0x1fC0000000000 & value){ // => 56 bit representation (49 bit value)
            bytes_to_write = 7;
          }
          else if (    0x3f800000000 & value){ // => 48 bit representation (42 bit representation)
            bytes_to_write = 6;
          }
          else if (0x7f0000000 & value){ // => 40 bit representation (35 bit representation)
            bytes_to_write = 5;
          }
          else if (0xfe00000 & value){ // => 32 bit representation (28 bit representation)
            bytes_to_write = 4;
          }
          else if (0x1fc000 & value){ // => 24 bit representation (21 bit representation)
            bytes_to_write = 3;
          }
          else if (0x7f80 & value){ // => 16 bit representation (14 bit representation)
            bytes_to_write = 2;
          } else { // 8bit representation (7 bit value)
            bytes_to_write = 1;
          }
          for (unsigned short i = 0; i != bytes_to_write;++i,value >>= 7){
              *addr = value & 0x7F | (i + 1 != bytes_to_write ? 0x80:0);
              ++addr;
          }
          return bytes_to_write;
   }

  template<typename T> struct mem_tag{

  };
  template<> struct mem_tag<std::int32_t>{
     using tag_t = signed char;
     static const tag_t tag = 5;
     static const tag_t rle_tag = -5;
     static const size_t tag_len = sizeof(tag_t);
  };

  struct tag_match_result_t{
      operator bool(){return match;}
      bool match;
      bool rle;
  };

  template<typename T> struct type_handler:public mem_tag<T>{
      static size_t write_tag(char* addr,bool rle = false){
          *((typename mem_tag<T>::tag_t*)addr) = rle?mem_tag<T>::rle_tag:mem_tag<T>::tag;
          return mem_tag<T>::tag_len;
      }
      static void write_length_7bit_encoded(char* addr,int v){
          *addr = v;
      }
      static size_t increment_7bit_encoded(char* addr,size_t width){
          unsigned long long int stored_value = 0;
          stored_value = basic::read_base128_ull((unsigned char*) addr,width);
          ++stored_value;
          return  write_base128( (unsigned char*)addr, stored_value);
      }
      static tag_match_result_t tag_match(char* addr){
          if (*addr == mem_tag<T>::tag || *addr == mem_tag<T>::rle_tag)
           return{true,*addr == mem_tag<T>::rle_tag};
          return {false,false};
      }
  };

  class mem{
      public:
        struct seg_info{
            char* type_seg_          = {};
            char* info_seg_          = {};
            size_t type_seg_size_    = {};
            size_t info_seg_size_    = {};
            size_t type_seg_ofs_     = {};
            size_t info_seg_ofs_     = {};
            size_t info_seg_written_ = {};
            size_t type_seg_written_ = {};
        };
        using set_mem_result_t = seg_info;
        using write_result_t = std::pair<size_t,size_t>;
      private:
        seg_info segs_ = {};
      public:
        set_mem_result_t set_mem(seg_info new_seg_info){
            auto t = segs_;
            segs_ = new_seg_info;
            return segs_;
        }
        write_result_t write_unchecked(std::int32_t v,bool write_through = true){
            //Write Data
            if (write_through) *((decltype(v)*) (segs_.info_seg_+segs_.info_seg_written_) ) = v;
            segs_.info_seg_written_ += sizeof(v);
            //Write Type
            if (segs_.type_seg_ofs_ == segs_.type_seg_written_){
                //Start of a data
                segs_.type_seg_written_ += type_handler<decltype(v)>::write_tag(segs_.type_seg_ + segs_.type_seg_ofs_);
            } else if (auto r = type_handler<decltype(v)>::tag_match(segs_.type_seg_ + segs_.type_seg_ofs_)) {
                if(!r.rle) {
                    type_handler<decltype(v)>::write_tag(segs_.type_seg_ + segs_.type_seg_ofs_,true);
                    type_handler<decltype(v)>::write_length_7bit_encoded(segs_.type_seg_ + segs_.type_seg_ofs_ + 1,2);
                    ++segs_.type_seg_written_;
                } else {
                    auto cur_width_of_len_tag = segs_.type_seg_written_ - segs_.type_seg_ofs_ - 1;
                    auto cur_width = type_handler<decltype(v)>::increment_7bit_encoded(segs_.type_seg_ + segs_.type_seg_ofs_ + 1,segs_.type_seg_written_ - segs_.type_seg_ofs_ - 1);
                    if (cur_width > cur_width_of_len_tag) segs_.type_seg_written_ += cur_width - cur_width_of_len_tag;
                }
            }
            return {};
        }
        std::ostream& dump_info(std::ostream& os){
            for(size_t i = 0;i != segs_.info_seg_written_;++i){
             if (i % 16 == 0) os << "\n";
             os << (int)*( ((unsigned char *)segs_.info_seg_)+i) << ' ';
            }
            return os;
        }
        std::ostream& dump_type(std::ostream& os){
            for(size_t i = 0;i != segs_.type_seg_written_;++i){
             if (i % 16 == 0) os << "\n";
             os << (int)*( (unsigned char *) segs_.type_seg_+i) << ' ';
            }
            return os;
        }

  };
 }
}

namespace ceps{
 namespace serialization{
   namespace basic{
     namespace tests{
       void dump_data(unsigned char* buffer, size_t elems){
         for(size_t i = 0; i != elems;++i)
          std::cout << (unsigned int)buffer[i] << (i % 16 == 0 ? "\n":" ");
       }
       void read_write_128_base(){
         unsigned char buffer[128];
         auto wr1 = write_base128(buffer, 0);
         auto rr1 = read_base128_ull(buffer);
         std::cout << "bytes written:"<< wr1 << " value read:" << rr1 << "\n";
         auto wr2 = write_base128(buffer, 1);
         auto rr2 = read_base128_ull(buffer);
         std::cout << "bytes written:"<< wr2 << " value read:" << rr2 << "\n";
         auto wr3 = write_base128(buffer, 127);
         auto rr3 = read_base128_ull(buffer);
         std::cout << "bytes written:"<< wr3 << " value read:" << rr3 << "\n";
         auto wr4 = write_base128(buffer, 128);
         auto rr4 = read_base128_ull(buffer);
         std::cout << "bytes written:"<< wr4 << " value read:" << rr4 << "\n";

       }
     }
   }
  }
}
int main(){
    ceps::serialization::basic::tests::read_write_128_base();
    return 0;
    std::cout << "Serialization Study I\n";
    constexpr auto mem_size = 1024*1024;
    char* info_seg = new char[mem_size];
    char* type_seg = new char[mem_size];
    ceps::serialization::mem mem;
    //for (int i = 0; i <= 16384;++i)
    // mem.write_unchecked(i,false);
    //1  2  4  8  16  32  64  128 256 512 1024 2048 4096 8192  16384 32768  65536  131072  262144  524288  1048576
    //0  1  2  3  4   5   6   7   8   9   10   11   12   13    14    15     16     17      18      19      20
    //|-------- 0 - 127----| |----------128 -16383 ---------| | -------------- 16384 - 1048575 -------------------|

    for (unsigned int i = 0; i <= 63;++i){
        mem.set_mem({info_seg,type_seg,mem_size,mem_size,0,0,0,0});
        for(unsigned long long j=0;j < 1 << i; ++j)
          mem.write_unchecked(j,false);
        std::cerr << "\nType Segment:2^"<< i << ":";
        mem.dump_type(std::cerr);
    }

    //std::cout << "Info Segment:\n";mem.dump_info(std::cout);std::cout << "\n\n";
    //std::cout << "Type Segment:\n";mem.dump_type(std::cout);
}<commit_msg>Tests<commit_after>#include <iostream>
#include <iomanip>
#include <tuple>
#include <limits>
#include <cstring>
#include <cassert>

namespace ceps{
 namespace serialization{
   namespace basic{
     constexpr unsigned long long inline read_base128_ull(unsigned char* addr, unsigned short max_width = 10)
     {
        unsigned long long r = *((unsigned long long*)addr);
        if ( (r & 0x80) == 0) return r & 0x7f;
        else if ( (r & 0x8000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1);
        else if ( (r & 0x800000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2);
        else if ( (r & 0x80000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) ;
        else if ( (r & 0x8000000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                ((r & 0x7f00000000) >> 4) ;
        else if ( (r & 0x800000000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) ;
        else if ( (r & 0x80000000000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) | ((r & 0x7f000000000000) >> 6);
        else if ( (r & 0x8000000000000000) == 0)
         return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) |
                ((r & 0x7f000000000000) >> 6) | ((r & 0x7f00000000000000) >> 7);
        else if ((*(addr + sizeof(unsigned long long int)) & 0x80) == 0)
          return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
                 ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) |
                 ((r & 0x7f000000000000) >> 6) | ((r & 0x7f00000000000000) >> 7) |
                 ((unsigned long long int)(*(addr + sizeof(unsigned long long int)) & 0x7f) << 56);
        return (r & 0x7f) | ((r & 0x7f00) >> 1) | ((r & 0x7f0000) >> 2) | ((r & 0x7f000000) >> 3) |
               ((r & 0x7f00000000) >> 4) | ((r & 0x7f0000000000) >> 5) |
               ((r & 0x7f000000000000) >> 6) | ((r & 0x7f00000000000000) >> 7) |
               ((unsigned long long int)(*(addr + sizeof(unsigned long long int)) & 0x7f) << 56)|
               ((unsigned long long int)(*(addr + sizeof(unsigned long long int)+1) & 0x01) << 63);
     }
   }
   unsigned short write_base128(unsigned char* addr, unsigned long long value){
          unsigned short bytes_to_write = 0;
          if (0x8000000000000000 & value){ // => 80 bit representation (64 bit value)
            bytes_to_write = 10;
          }
          else if (0x7f00000000000000 & value){ // => 72 bit representation (63 bit value)
            bytes_to_write = 9;
          }
          else if (0xfe000000000000 & value){ // => 64 bit representation (56 bit value)
            bytes_to_write = 8;
          }
          else if (  0x1fC0000000000 & value){ // => 56 bit representation (49 bit value)
            bytes_to_write = 7;
          }
          else if (    0x3f800000000 & value){ // => 48 bit representation (42 bit representation)
            bytes_to_write = 6;
          }
          else if (0x7f0000000 & value){ // => 40 bit representation (35 bit representation)
            bytes_to_write = 5;
          }
          else if (0xfe00000 & value){ // => 32 bit representation (28 bit representation)
            bytes_to_write = 4;
          }
          else if (0x1fc000 & value){ // => 24 bit representation (21 bit representation)
            bytes_to_write = 3;
          }
          else if (0x7f80 & value){ // => 16 bit representation (14 bit representation)
            bytes_to_write = 2;
          } else { // 8bit representation (7 bit value)
            bytes_to_write = 1;
          }
          for (unsigned short i = 0; i != bytes_to_write;++i,value >>= 7){
              *addr = value & 0x7F | (i + 1 != bytes_to_write ? 0x80:0);
              ++addr;
          }
          return bytes_to_write;
   }

   unsigned short write_base128(unsigned char* addr, unsigned int value){
          return write_base128(addr, (unsigned long long) value);
   }

   unsigned short write_base128(unsigned char* addr, unsigned short value){
          return write_base128(addr, (unsigned long long) value);
   }

   unsigned short write_base128(unsigned char* addr, unsigned char value){
          return write_base128(addr, (unsigned long long) value);
   }

  template<typename T> struct mem_tag{

  };
  template<> struct mem_tag<std::int32_t>{
     using tag_t = signed char;
     static const tag_t tag = 5;
     static const tag_t rle_tag = -5;
     static const size_t tag_len = sizeof(tag_t);
  };

  struct tag_match_result_t{
      operator bool(){return match;}
      bool match;
      bool rle;
  };

  template<typename T> struct type_handler:public mem_tag<T>{
      static size_t write_tag(char* addr,bool rle = false){
          *((typename mem_tag<T>::tag_t*)addr) = rle?mem_tag<T>::rle_tag:mem_tag<T>::tag;
          return mem_tag<T>::tag_len;
      }
      static void write_length_7bit_encoded(char* addr,int v){
          *addr = v;
      }
      static size_t increment_7bit_encoded(char* addr,size_t width){
          unsigned long long int stored_value = 0;
          stored_value = basic::read_base128_ull((unsigned char*) addr,width);
          ++stored_value;
          return  write_base128( (unsigned char*)addr, stored_value);
      }
      static tag_match_result_t tag_match(char* addr){
          if (*addr == mem_tag<T>::tag || *addr == mem_tag<T>::rle_tag)
           return{true,*addr == mem_tag<T>::rle_tag};
          return {false,false};
      }
  };

  class mem{
      public:
        struct seg_info{
            char* type_seg_          = {};
            char* info_seg_          = {};
            size_t type_seg_size_    = {};
            size_t info_seg_size_    = {};
            size_t type_seg_ofs_     = {};
            size_t info_seg_ofs_     = {};
            size_t info_seg_written_ = {};
            size_t type_seg_written_ = {};
        };
        using set_mem_result_t = seg_info;
        using write_result_t = std::pair<size_t,size_t>;
      private:
        seg_info segs_ = {};
      public:
        set_mem_result_t set_mem(seg_info new_seg_info){
            auto t = segs_;
            segs_ = new_seg_info;
            return segs_;
        }
        write_result_t write_unchecked(std::int32_t v,bool write_through = true){
            //Write Data
            if (write_through) *((decltype(v)*) (segs_.info_seg_+segs_.info_seg_written_) ) = v;
            segs_.info_seg_written_ += sizeof(v);
            //Write Type
            if (segs_.type_seg_ofs_ == segs_.type_seg_written_){
                //Start of a data
                segs_.type_seg_written_ += type_handler<decltype(v)>::write_tag(segs_.type_seg_ + segs_.type_seg_ofs_);
            } else if (auto r = type_handler<decltype(v)>::tag_match(segs_.type_seg_ + segs_.type_seg_ofs_)) {
                if(!r.rle) {
                    type_handler<decltype(v)>::write_tag(segs_.type_seg_ + segs_.type_seg_ofs_,true);
                    type_handler<decltype(v)>::write_length_7bit_encoded(segs_.type_seg_ + segs_.type_seg_ofs_ + 1,2);
                    ++segs_.type_seg_written_;
                } else {
                    auto cur_width_of_len_tag = segs_.type_seg_written_ - segs_.type_seg_ofs_ - 1;
                    auto cur_width = type_handler<decltype(v)>::increment_7bit_encoded(segs_.type_seg_ + segs_.type_seg_ofs_ + 1,segs_.type_seg_written_ - segs_.type_seg_ofs_ - 1);
                    if (cur_width > cur_width_of_len_tag) segs_.type_seg_written_ += cur_width - cur_width_of_len_tag;
                }
            }
            return {};
        }
        std::ostream& dump_info(std::ostream& os){
            for(size_t i = 0;i != segs_.info_seg_written_;++i){
             if (i % 16 == 0) os << "\n";
             os << (int)*( ((unsigned char *)segs_.info_seg_)+i) << ' ';
            }
            return os;
        }
        std::ostream& dump_type(std::ostream& os){
            for(size_t i = 0;i != segs_.type_seg_written_;++i){
             if (i % 16 == 0) os << "\n";
             os << (int)*( (unsigned char *) segs_.type_seg_+i) << ' ';
            }
            return os;
        }

  };
 }
}

namespace ceps{
 namespace serialization{
   namespace basic{
     namespace tests{
       void dump_data(unsigned char* buffer, size_t elems){
         for(size_t i = 0; i != elems;++i)
          std::cout << std::setw(4) << std::setfill(' ') << (unsigned int)buffer[i] << ((i+1) % 16 == 0 ? "\n":" ");
       }
       void read_write_128_base(){
         constexpr auto buf_size = 128;
         unsigned char buffer[buf_size];// = {0};
         auto read_write_128_base_step = [&](unsigned long long v){
                    memset(buffer,0,buf_size);
                    auto wr = write_base128(buffer, v);
                    auto rr = read_base128_ull(buffer);
                    if (v!=rr){
                      std::cout << "bytes written:"<< wr << " value read:" << rr << " value expected: " << v << "\n";
                      dump_data(buffer,buf_size);
                      assert(v==rr);
                    }
         };
            //1  2  4  8  16  32  64  128 256 512 1024 2048 4096 8192  16384 32768  65536  131072  262144  524288  1048576
            //0  1  2  3  4   5   6   7   8   9   10   11   12   13    14    15     16     17      18      19      20
            //|-------- 0 - 127----| |----------128 -16383 ---------| | -------------- 16384 - 1048575 -------------------|

         for (auto v : {0ull,1ull,127ull,128ull,129ull,16383ull,16384ull,32768ull,1048676ull,1048677ull,
                        0x0ull,0xfull,0xffull,0xfffull,0xffffull,0xfffffull,0xffffffull,0xfffffffull,0xffffffffull,0xfffffffffull,0xffffffffffull,
                        0xfffffffffffull,0xffffffffffffull,0xfffffffffffffull,0xffffffffffffffull,0xfffffffffffffffull, 0xffffffffffffffffull,
                        0x1ull,0xeull,0xfeull,0xefull,0xfffull,0xeffull,0xaffull,0xbf3ull,0xffffull,0xfffffull,0xffffffull,0xfffffffull,0xffffffffull,
                        0xfffffffffull,0xffffffffffull,0xfffffffffffull,0xffffffffffffull,0xfffffffffffffull,0xffffffffffffffull,0xfffffffffffffffull,
                        0xffffffffffffffffull,
                         }
                        )
           read_write_128_base_step(v);
       }
       void run_all(){
         read_write_128_base();
       }
     }
   }
  }
}

int main(){
    ceps::serialization::basic::tests::run_all();
}<|endoftext|>


<commit_before>#pragma once

#include <memory>
#include <logger_export.h>

namespace logger
{
    class LOGGER_EXPORT ILogger
    {
    public:
        virtual ~ILogger() {};
        virtual void Trace(const std::string& message) = 0;
        virtual void Error(const std::string& message) = 0;
    };

    LOGGER_EXPORT ILogger* createMainLogger();
    LOGGER_EXPORT ILogger* getLogger(const std::string& module);
}
<commit_msg>Include string<commit_after>#pragma once

#include <string>

#include <logger_export.h>

namespace logger
{
    class LOGGER_EXPORT ILogger
    {
    public:
        virtual ~ILogger() {};
        virtual void Trace(const std::string& message) = 0;
        virtual void Error(const std::string& message) = 0;
    };

    LOGGER_EXPORT ILogger* createMainLogger();
    LOGGER_EXPORT ILogger* getLogger(const std::string& module);
}
<|endoftext|>


<commit_before>/*
** Copyright 1994 by Miron Livny, and Mike Litzkow
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted,
** provided that the above copyright notice appear in all copies and that
** both that copyright notice and this permission notice appear in
** supporting documentation, and that the names of the University of
** Wisconsin and the copyright holders not be used in advertising or
** publicity pertaining to distribution of the software without specific,
** written prior permission.  The University of Wisconsin and the
** copyright holders make no representations about the suitability of this
** software for any purpose.  It is provided "as is" without express
** or implied warranty.
**
** THE UNIVERSITY OF WISCONSIN AND THE COPYRIGHT HOLDERS DISCLAIM ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE UNIVERSITY OF
** WISCONSIN OR THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT
** OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
** OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
** OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
** OR PERFORMANCE OF THIS SOFTWARE.
**
** Author:  Mike Litzkow
**
*/

/*
  Build site specific versions of config and script files by dialoging
  with the user to get/confirm settings.
*/

#define _POSIX_SOURCE

#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "custom.h"

const int MATCH = 0;	// for strcmp()

int check_dir( const char *path );
int check_exec( const char *path );
char * xlate_tilde( const char *path );
char * lookup_tilde( char *orig,  const char *user );
int check_host( const char *name );

/*
  All the macros which are to be customized should go here.  Parameters
  are:
	Macro name
	Description
	Default value
*/
Macro release_dir(
	"RELEASEDIR",
	"Full pathname of the parent directory of Condor's \"bin\" and \"lib\"\n\
directories.  For example: specifying \"/usr/psup/condor\" means that\n\
users will find Condor libraries and executables in \"/usr/psup/condor/lib\"\n\
and \"/usr/psup/condor/bin\" respectively.",
	"/usr/psup/condor"
);
Macro condor_host(
	"CONDOR_HOST",
	"Host where central manager should run, this should be a fully qualified\n\
internet domain name.",
	"frigg.cs.wisc.edu"
);
Macro condor_admin(
	"CONDOR_ADMIN",
"Address of the local condor administrator, for automatically generated\n\
mail regarding problems",
	"condor-admin"
);
Macro condor_developers(
	"CONDOR_DEVELOPERS",
"Address of condor development team at University of Wisconsin, for\n\
automatically generated mail regarding status of Condor at your site",
	"condor-admin@cs.wisc.edu"
);
Macro local_dir(
	"LOCAL_DIR",
"Parent directory for machine specific directories \"spool\", \"log\", and\n\
\"execute\".  Specifying $(TILDE) means condor's home directory",
	"$(TILDE)"
);
Macro has_afs(
	"HAS_AFS",
	"Does this machine run AFS?",
	"TRUE"
);
Macro use_afs(
	"USE_AFS",
	"Do you want to use AFS for condor file access?",
	"FALSE"
);
Macro fs_path(
	"FS_PATHNAME",
	"Pathname of the AFS \"fs\" command",
	"/usr/afsws/bin/fs"
);
Macro vos_path(
	"VOS_PATHNAME",
	"Pathname of the AFS \"vos\" command",
	"/usr/afsws/etc/vos"
);
Macro mailer_path(
	"MAIL",
	"Pathname of user level program Condor software should use to send mail",
#if defined(SUNOS41) || defined(ULTRIX43)
	"/usr/ucb/mail"
#else
	"/bin/mail"
#endif
);
Macro uid_domain(
	"UID_DOMAIN",
	"Internet domain of machines sharing a common UID space.  If you\n\
specify a UID space, Condor will execute user jobs under the\n\
UID of the submitting user - otherwise Condor will execute user\n\
jobs with the UID \"nobody\".  Specify \"none\" unless all machines\n\
in your pool are guaranteed to have consistent UIDs.",
	"cs.wisc.edu"
);
Macro filesystem_domain(
	"FILESYSTEM_DOMAIN",
	"\nInternet domain of machines sharing a common NFS file space",
	"cs.wisc.edu"
);

int
main()
{
	ConfigFile	*file;
	char		dir[_POSIX_PATH_MAX];
	int			we_have_afs = 0;
	int			we_have_fs_domain = 0;

		// Customize the macros by dialoging with the user
	condor_host.init( check_host );
	condor_admin.init();
	condor_developers.init();
	release_dir.init( check_dir );
	local_dir.init( check_dir );
	if( confirm("Will all machines in your pool participate in a common file system via AFS? ") ) {
		we_have_afs = 1;
		has_afs.init( TRUE );
		if( confirm("\nDo you want to use AFS for condor file access? (This may not have\n a positive impact on performance.)") ) {
			use_afs.init( TRUE );
		} else {
			use_afs.init( FALSE );
		}
		fs_path.init( check_exec );
		vos_path.init( check_exec );
	} else {
		has_afs.init( FALSE );
	}
	mailer_path.init( check_exec );
	uid_domain.init();
	if( confirm("Will all machines in your pool participate in a common file system via NFS? ") ) {
		we_have_fs_domain = 1;
		filesystem_domain.init();
	}

		// Make user confirm that everything is correct
	printf( "Please Confirm:\n" );
	printf( "\t%s\n", release_dir.gen() );
	printf( "\t%s\n", condor_host.gen() );
	printf( "\t%s\n", condor_admin.gen() );
	printf( "\t%s\n", condor_developers.gen() );
	printf( "\t%s\n", local_dir.gen() );
	printf( "\t%s\n", has_afs.gen() );
	printf( "\t%s\n", use_afs.gen() );
	if( we_have_afs ) {
		printf( "\t%s\n", fs_path.gen() );
		printf( "\t%s\n", vos_path.gen() );
	}
	printf( "\t%s\n", mailer_path.gen() );
	printf( "\t%s\n", uid_domain.gen() );
	if( we_have_fs_domain ) {
		printf( "\t%s\n", filesystem_domain.gen() );
	}
	if( !confirm("Are all the above settings correct? ") ) {
		printf( "Configuration Aborted\n" );
		return 1;
	}

		// Prepare to customize the files in the "lib" directory.
	strcpy( dir, release_dir.get_val() );
	strcat( dir, "/lib" );
	file = new ConfigFile( dir );

		// Customize "condor_config"
	file->begin( "condor_config" );
	file->add_macro( release_dir.gen() );
	file->add_macro( condor_host.gen() );
	file->add_macro( condor_admin.gen() );
	file->add_macro( condor_developers.gen() );
	file->add_macro( local_dir.gen() );
	file->add_macro( has_afs.gen() );
	if( we_have_afs ) {
		file->add_macro( use_afs.gen() );
		file->add_macro( fs_path.gen() );
		file->add_macro( vos_path.gen() );
	}
	file->add_macro( mailer_path.gen() );
	file->add_macro( uid_domain.gen() );
	if( we_have_fs_domain ) {
		file->add_macro( filesystem_domain.gen() );
	}
	file->end();

		// Customize "config_off"
	file->begin( "config_off" );
	file->add_macro( release_dir.gen(TRUE) );
	file->end();

		// Customize "config_on"
	file->begin( "config_on" );
	file->add_macro( release_dir.gen(TRUE) );
	file->end();

		// Prepare to customize the files in the "bin" directory.
	delete file;
	strcpy( dir, release_dir.get_val() );
	strcat( dir, "/bin" );
	file = new ConfigFile( dir );

		// Customize "condor_init"
	file->begin( "condor_init" );
	file->add_macro( "#!/bin/csh -f" );
	file->add_macro( "" );
	file->add_macro( release_dir.gen(TRUE) );
	file->end();

		// Customize "condor_throttle"
	file->begin( "condor_throttle" );
	file->add_macro( "#!/bin/csh -f" );
	file->add_macro( "" );
	file->add_macro( release_dir.gen(TRUE) );
	file->end();

	delete file;
	printf( "\nCustomization Complete\n" );

	return 0;
}

/*
  Check a directory for validity.  We only check that this is a real
  directory on the system - no permissions or other reasonableness
  criteria are checked.  The directory name may contain the component
  $(TILDE) which is interpreted to mean "~condor".
*/
int
check_dir( const char *path )
{
	struct stat	buf;
	char		*tmp;

	if( path[0] != '/' && path[0] != '$' ) {
		printf( "Must supply a full pathname starting with \"/\"\n" );
		return FALSE;
	}

	tmp = xlate_tilde( path );

	if( stat(tmp,&buf) < 0 ) {
		printf( "Warning: \"%s\" is not a valid directory\n", path );
		return FALSE;
	}

	if( S_ISDIR(buf.st_mode) ) {
		return TRUE;
	} else {
		printf( "Warning: \"%s\" is not a valid directory\n", path );
		return FALSE;
	}
}

/*
  Translate a pathname which may contain $(TILDE) to a simple pathname.
*/
char *
xlate_tilde( const char *path )
{
	static char answer[_POSIX_PATH_MAX];
	char	*component;
	char	*tmp;

	tmp = new char[ strlen(path) + 1 ];
	strcpy( tmp, path );

	component = strtok( tmp, "/" );
	if( strcmp("$(TILDE)",component) == MATCH ) {
		component = lookup_tilde( component, "condor" );
	}
	strcpy( answer, "/" );
	strcat( answer, component );

	while( component = strtok(NULL,"/") ) {
		if( strcmp("$(TILDE)",component) == MATCH ) {
			component = lookup_tilde( component, "condor" );
		}
		strcat( answer, "/" );
		strcat( answer, component );
	}
	delete [] tmp;
	return answer;
}

/*
  Lookup the given user's home directory.
*/
#include <pwd.h>
char *
lookup_tilde( char *orig,  const char *user )
{
	struct passwd *entry;

	if( (entry = getpwnam(user)) == NULL ) {
		printf( "Warning: Can't find user \"%s\" in passwd file\n", user );
		return orig;
	}
	return entry->pw_dir + 1;
}

extern "C" {
#	include <netdb.h>
}
int check_host( const char *name )
{
	struct hostent	*hp;

	if( gethostbyname(name) ) {
		return TRUE;
	} else {
		printf( "Warning: Can't locate host \"%s\"\n", name );
		return FALSE;
	}
}

/*
  Check a pathname for an executable program for validity.  The
  pathname may contain the component $(TILDE) which is interpreted to
  mean "~condor".
*/
int
check_exec( const char *path )
{
	struct stat	buf;
	char		*tmp;

	if( path[0] != '/' && path[0] != '$' ) {
		printf( "Must supply a full pathname starting with \"/\"\n" );
		return FALSE;
	}

	tmp = xlate_tilde( path );

	if( stat(tmp,&buf) < 0 ) {
		printf( "Warning: \"%s\" is not a valid pathname\n", path );
		return FALSE;
	}

	if( S_IXUSR & buf.st_mode ) {
		return TRUE;
	} else {
		printf( "Warning: \"%s\" is not an executable file\n", path );
		return FALSE;
	}
}
<commit_msg>Moved call to use_afs.gen() inside test for we_have_afs.  If the user answers no to has_afs, then use_afs is never asked, thus having no value, and use_afs.gen() causes a segmentation fault.<commit_after>/*
** Copyright 1994 by Miron Livny, and Mike Litzkow
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted,
** provided that the above copyright notice appear in all copies and that
** both that copyright notice and this permission notice appear in
** supporting documentation, and that the names of the University of
** Wisconsin and the copyright holders not be used in advertising or
** publicity pertaining to distribution of the software without specific,
** written prior permission.  The University of Wisconsin and the
** copyright holders make no representations about the suitability of this
** software for any purpose.  It is provided "as is" without express
** or implied warranty.
**
** THE UNIVERSITY OF WISCONSIN AND THE COPYRIGHT HOLDERS DISCLAIM ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE UNIVERSITY OF
** WISCONSIN OR THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT
** OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
** OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
** OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
** OR PERFORMANCE OF THIS SOFTWARE.
**
** Author:  Mike Litzkow
**
*/

/*
  Build site specific versions of config and script files by dialoging
  with the user to get/confirm settings.
*/

#define _POSIX_SOURCE

#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "custom.h"

const int MATCH = 0;	// for strcmp()

int check_dir( const char *path );
int check_exec( const char *path );
char * xlate_tilde( const char *path );
char * lookup_tilde( char *orig,  const char *user );
int check_host( const char *name );

/*
  All the macros which are to be customized should go here.  Parameters
  are:
	Macro name
	Description
	Default value
*/
Macro release_dir(
	"RELEASEDIR",
	"Full pathname of the parent directory of Condor's \"bin\" and \"lib\"\n\
directories.  For example: specifying \"/usr/psup/condor\" means that\n\
users will find Condor libraries and executables in \"/usr/psup/condor/lib\"\n\
and \"/usr/psup/condor/bin\" respectively.",
	"/usr/psup/condor"
);
Macro condor_host(
	"CONDOR_HOST",
	"Host where central manager should run, this should be a fully qualified\n\
internet domain name.",
	"frigg.cs.wisc.edu"
);
Macro condor_admin(
	"CONDOR_ADMIN",
"Address of the local condor administrator, for automatically generated\n\
mail regarding problems",
	"condor-admin"
);
Macro condor_developers(
	"CONDOR_DEVELOPERS",
"Address of condor development team at University of Wisconsin, for\n\
automatically generated mail regarding status of Condor at your site",
	"condor-admin@cs.wisc.edu"
);
Macro local_dir(
	"LOCAL_DIR",
"Parent directory for machine specific directories \"spool\", \"log\", and\n\
\"execute\".  Specifying $(TILDE) means condor's home directory",
	"$(TILDE)"
);
Macro has_afs(
	"HAS_AFS",
	"Does this machine run AFS?",
	"TRUE"
);
Macro use_afs(
	"USE_AFS",
	"Do you want to use AFS for condor file access?",
	"FALSE"
);
Macro fs_path(
	"FS_PATHNAME",
	"Pathname of the AFS \"fs\" command",
	"/usr/afsws/bin/fs"
);
Macro vos_path(
	"VOS_PATHNAME",
	"Pathname of the AFS \"vos\" command",
	"/usr/afsws/etc/vos"
);
Macro mailer_path(
	"MAIL",
	"Pathname of user level program Condor software should use to send mail",
#if defined(SUNOS41) || defined(ULTRIX43)
	"/usr/ucb/mail"
#else
	"/bin/mail"
#endif
);
Macro uid_domain(
	"UID_DOMAIN",
	"Internet domain of machines sharing a common UID space.  If you\n\
specify a UID space, Condor will execute user jobs under the\n\
UID of the submitting user - otherwise Condor will execute user\n\
jobs with the UID \"nobody\".  Specify \"none\" unless all machines\n\
in your pool are guaranteed to have consistent UIDs.",
	"cs.wisc.edu"
);
Macro filesystem_domain(
	"FILESYSTEM_DOMAIN",
	"\nInternet domain of machines sharing a common NFS file space",
	"cs.wisc.edu"
);

int
main()
{
	ConfigFile	*file;
	char		dir[_POSIX_PATH_MAX];
	int			we_have_afs = 0;
	int			we_have_fs_domain = 0;

		// Customize the macros by dialoging with the user
	condor_host.init( check_host );
	condor_admin.init();
	condor_developers.init();
	release_dir.init( check_dir );
	local_dir.init( check_dir );
	if( confirm("Will all machines in your pool participate in a common file system via AFS? ") ) {
		we_have_afs = 1;
		has_afs.init( TRUE );
		if( confirm("\nDo you want to use AFS for condor file access? (This may not have\n a positive impact on performance.)") ) {
			use_afs.init( TRUE );
		} else {
			use_afs.init( FALSE );
		}
		fs_path.init( check_exec );
		vos_path.init( check_exec );
	} else {
		has_afs.init( FALSE );
	}
	mailer_path.init( check_exec );
	uid_domain.init();
	if( confirm("Will all machines in your pool participate in a common file system via NFS? ") ) {
		we_have_fs_domain = 1;
		filesystem_domain.init();
	}

		// Make user confirm that everything is correct
	printf( "Please Confirm:\n" );
	printf( "\t%s\n", release_dir.gen() );
	printf( "\t%s\n", condor_host.gen() );
	printf( "\t%s\n", condor_admin.gen() );
	printf( "\t%s\n", condor_developers.gen() );
	printf( "\t%s\n", local_dir.gen() );
	printf( "\t%s\n", has_afs.gen() );
	if( we_have_afs ) {
		printf( "\t%s\n", use_afs.gen() );
		printf( "\t%s\n", fs_path.gen() );
		printf( "\t%s\n", vos_path.gen() );
	}
	printf( "\t%s\n", mailer_path.gen() );
	printf( "\t%s\n", uid_domain.gen() );
	if( we_have_fs_domain ) {
		printf( "\t%s\n", filesystem_domain.gen() );
	}
	if( !confirm("Are all the above settings correct? ") ) {
		printf( "Configuration Aborted\n" );
		return 1;
	}

		// Prepare to customize the files in the "lib" directory.
	strcpy( dir, release_dir.get_val() );
	strcat( dir, "/lib" );
	file = new ConfigFile( dir );

		// Customize "condor_config"
	file->begin( "condor_config" );
	file->add_macro( release_dir.gen() );
	file->add_macro( condor_host.gen() );
	file->add_macro( condor_admin.gen() );
	file->add_macro( condor_developers.gen() );
	file->add_macro( local_dir.gen() );
	file->add_macro( has_afs.gen() );
	if( we_have_afs ) {
		file->add_macro( use_afs.gen() );
		file->add_macro( fs_path.gen() );
		file->add_macro( vos_path.gen() );
	}
	file->add_macro( mailer_path.gen() );
	file->add_macro( uid_domain.gen() );
	if( we_have_fs_domain ) {
		file->add_macro( filesystem_domain.gen() );
	}
	file->end();

		// Customize "config_off"
	file->begin( "config_off" );
	file->add_macro( release_dir.gen(TRUE) );
	file->end();

		// Customize "config_on"
	file->begin( "config_on" );
	file->add_macro( release_dir.gen(TRUE) );
	file->end();

		// Prepare to customize the files in the "bin" directory.
	delete file;
	strcpy( dir, release_dir.get_val() );
	strcat( dir, "/bin" );
	file = new ConfigFile( dir );

		// Customize "condor_init"
	file->begin( "condor_init" );
	file->add_macro( "#!/bin/csh -f" );
	file->add_macro( "" );
	file->add_macro( release_dir.gen(TRUE) );
	file->end();

		// Customize "condor_throttle"
	file->begin( "condor_throttle" );
	file->add_macro( "#!/bin/csh -f" );
	file->add_macro( "" );
	file->add_macro( release_dir.gen(TRUE) );
	file->end();

	delete file;
	printf( "\nCustomization Complete\n" );

	return 0;
}

/*
  Check a directory for validity.  We only check that this is a real
  directory on the system - no permissions or other reasonableness
  criteria are checked.  The directory name may contain the component
  $(TILDE) which is interpreted to mean "~condor".
*/
int
check_dir( const char *path )
{
	struct stat	buf;
	char		*tmp;

	if( path[0] != '/' && path[0] != '$' ) {
		printf( "Must supply a full pathname starting with \"/\"\n" );
		return FALSE;
	}

	tmp = xlate_tilde( path );

	if( stat(tmp,&buf) < 0 ) {
		printf( "Warning: \"%s\" is not a valid directory\n", path );
		return FALSE;
	}

	if( S_ISDIR(buf.st_mode) ) {
		return TRUE;
	} else {
		printf( "Warning: \"%s\" is not a valid directory\n", path );
		return FALSE;
	}
}

/*
  Translate a pathname which may contain $(TILDE) to a simple pathname.
*/
char *
xlate_tilde( const char *path )
{
	static char answer[_POSIX_PATH_MAX];
	char	*component;
	char	*tmp;

	tmp = new char[ strlen(path) + 1 ];
	strcpy( tmp, path );

	component = strtok( tmp, "/" );
	if( strcmp("$(TILDE)",component) == MATCH ) {
		component = lookup_tilde( component, "condor" );
	}
	strcpy( answer, "/" );
	strcat( answer, component );

	while( component = strtok(NULL,"/") ) {
		if( strcmp("$(TILDE)",component) == MATCH ) {
			component = lookup_tilde( component, "condor" );
		}
		strcat( answer, "/" );
		strcat( answer, component );
	}
	delete [] tmp;
	return answer;
}

/*
  Lookup the given user's home directory.
*/
#include <pwd.h>
char *
lookup_tilde( char *orig,  const char *user )
{
	struct passwd *entry;

	if( (entry = getpwnam(user)) == NULL ) {
		printf( "Warning: Can't find user \"%s\" in passwd file\n", user );
		return orig;
	}
	return entry->pw_dir + 1;
}

extern "C" {
#	include <netdb.h>
}
int check_host( const char *name )
{
	struct hostent	*hp;

	if( gethostbyname(name) ) {
		return TRUE;
	} else {
		printf( "Warning: Can't locate host \"%s\"\n", name );
		return FALSE;
	}
}

/*
  Check a pathname for an executable program for validity.  The
  pathname may contain the component $(TILDE) which is interpreted to
  mean "~condor".
*/
int
check_exec( const char *path )
{
	struct stat	buf;
	char		*tmp;

	if( path[0] != '/' && path[0] != '$' ) {
		printf( "Must supply a full pathname starting with \"/\"\n" );
		return FALSE;
	}

	tmp = xlate_tilde( path );

	if( stat(tmp,&buf) < 0 ) {
		printf( "Warning: \"%s\" is not a valid pathname\n", path );
		return FALSE;
	}

	if( S_IXUSR & buf.st_mode ) {
		return TRUE;
	} else {
		printf( "Warning: \"%s\" is not an executable file\n", path );
		return FALSE;
	}
}
<|endoftext|>


<commit_before>/*
 * libseaside - Library that provides an interface to the Contacts application
 * Copyright © 2010, Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 */

#include <QDebug>

#include <QStringList>

#include "seasideproxymodel.h"
#include "seasidesyncmodel.h"
#include "seaside.h"

class SeasideProxyModelPriv
{
public:
    SeasideProxyModel::FilterType filterType;
    SeasideProxyModel::SortType sortType;
};

SeasideProxyModel::SeasideProxyModel()
{
    priv = new SeasideProxyModelPriv;
    priv->filterType = FilterAll;
    priv->sortType = SortName;
    setDynamicSortFilter(true);
    setFilterKeyColumn(-1);
}

SeasideProxyModel::~SeasideProxyModel()
{
    delete priv;
}

void SeasideProxyModel::setFilter(FilterType filter)
{
    priv->filterType = filter;
    invalidateFilter();
}

void SeasideProxyModel::setSortType(SortType sortType)
{
    priv->sortType = sortType;
    if (priv->sortType == SortRecent)
        sort(Seaside::ColumnCommTimestamp, Qt::DescendingOrder);
    else
        sort(Seaside::ColumnFirstName, Qt::AscendingOrder);
}

bool SeasideProxyModel::filterAcceptsRow(int source_row,
                                         const QModelIndex& source_parent) const
{
    // TODO: add communication history

    if (!QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent))
        return false;

    if (priv->filterType == FilterAll)
        return true;

    SeasideSyncModel *model = dynamic_cast<SeasideSyncModel *>(sourceModel());
    if (!model)
        return true;

    QContact *contact = model->contact(source_row);

    if (priv->filterType == FilterRecent) {
        QDateTime cutoff = QDateTime::currentDateTime();
        cutoff = cutoff.addDays(-30);
        const QDateTime& dt = Seaside::contactCommTimestamp(contact);
        return dt.isValid() && (dt > cutoff);
    }
    else if (priv->filterType == FilterFavorites) {
        SEASIDE_SHORTCUTS;
        SEASIDE_SET_MODEL_AND_ROW(model, source_row);
        return SEASIDE_FIELD(Favorite, Bool);
    }
    else {
        qWarning() << "[ProxyModel] invalid filter type";
        return true;
    }
}

bool SeasideProxyModel::lessThan(const QModelIndex& left,
                                 const QModelIndex& right) const
{
    if (priv->sortType == SortName) {
        const QString& lStr = left.data(Seaside::DataRole).toString();
        const QString& rStr = right.data(Seaside::DataRole).toString();
        //qWarning() << "[ProxyModel] lessThan " << lStr << "VS" << rStr;
        return QString::localeAwareCompare(lStr, rStr) < 0;
    }
    else if (priv->sortType == SortRecent) {
        const QDateTime& lDate = left.data(Seaside::DataRole).toDateTime();
        const QDateTime& rDate = right.data(Seaside::DataRole).toDateTime();
        return lDate < rDate;
    }
    return false;
}
<commit_msg>Ensuring that a MeCard is always evaluated to be less than any other Contact in proxy model. Fix for BMC#6007 Contacts crashes when saving a contact with high possibility. Ensure proxy model and list are aligned in sort order. Signed-off-by: Connie Berardi <connie.berardi@intel.com><commit_after>/*
 * libseaside - Library that provides an interface to the Contacts application
 * Copyright © 2010, Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 */

#include <QDebug>

#include <QStringList>

#include "seasideproxymodel.h"
#include "seasidesyncmodel.h"
#include "seaside.h"

class SeasideProxyModelPriv
{
public:
    SeasideProxyModel::FilterType filterType;
    SeasideProxyModel::SortType sortType;
};

SeasideProxyModel::SeasideProxyModel()
{
    priv = new SeasideProxyModelPriv;
    priv->filterType = FilterAll;
    priv->sortType = SortName;
    setDynamicSortFilter(true);
    setFilterKeyColumn(-1);
}

SeasideProxyModel::~SeasideProxyModel()
{
    delete priv;
}

void SeasideProxyModel::setFilter(FilterType filter)
{
    priv->filterType = filter;
    invalidateFilter();
}

void SeasideProxyModel::setSortType(SortType sortType)
{
    priv->sortType = sortType;
    if (priv->sortType == SortRecent)
        sort(Seaside::ColumnCommTimestamp, Qt::DescendingOrder);
    else
        sort(Seaside::ColumnFirstName, Qt::AscendingOrder);
}

bool SeasideProxyModel::filterAcceptsRow(int source_row,
                                         const QModelIndex& source_parent) const
{
    // TODO: add communication history

    if (!QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent))
        return false;

    if (priv->filterType == FilterAll)
        return true;

    SeasideSyncModel *model = dynamic_cast<SeasideSyncModel *>(sourceModel());
    if (!model)
        return true;

    QContact *contact = model->contact(source_row);

    if (priv->filterType == FilterRecent) {
        QDateTime cutoff = QDateTime::currentDateTime();
        cutoff = cutoff.addDays(-30);
        const QDateTime& dt = Seaside::contactCommTimestamp(contact);
        return dt.isValid() && (dt > cutoff);
    }
    else if (priv->filterType == FilterFavorites) {
        SEASIDE_SHORTCUTS;
        SEASIDE_SET_MODEL_AND_ROW(model, source_row);
        return SEASIDE_FIELD(Favorite, Bool);
    }
    else {
        qWarning() << "[ProxyModel] invalid filter type";
        return true;
    }
}

bool SeasideProxyModel::lessThan(const QModelIndex& left,
                                 const QModelIndex& right) const
{

    SeasideSyncModel *model = dynamic_cast<SeasideSyncModel *>(sourceModel());
    if (!model)
        return true;

    SEASIDE_SHORTCUTS;
    SEASIDE_SET_MODEL_AND_ROW(model, left.row());
    const QString& lStr = SEASIDE_FIELD(FirstName, String);
    const bool isleftSelf = SEASIDE_FIELD(isSelf, Bool);

    SEASIDE_SET_MODEL_AND_ROW(model, right.row());
    const QString& rStr = SEASIDE_FIELD(FirstName, String);
    const bool isrightSelf = SEASIDE_FIELD(isSelf, Bool);

    //qWarning() << "[ProxyModel] lessThan isSelf left" << isleftSelf << " right" << isrightSelf;

    //MeCard should always be top of the list
    if(isleftSelf)
        return true;
    if(isrightSelf)
        return false;

    if (priv->sortType == SortName) {
      //qWarning() << "[ProxyModel] lessThan " << lStr << "VS" << rStr;
        return QString::localeAwareCompare(lStr, rStr) < 0;
    }
    else if (priv->sortType == SortRecent) {
        const QDateTime& lDate = left.data(Seaside::DataRole).toDateTime();
        const QDateTime& rDate = right.data(Seaside::DataRole).toDateTime();
        return lDate < rDate;
    }
    return false;
}
<|endoftext|>


<commit_before>#include "compiler/parse_table.h"
#include <string>

namespace tree_sitter {
    using std::string;
    using std::ostream;
    using std::to_string;
    using std::set;
    using std::vector;
    using rules::Symbol;

    ParseAction::ParseAction(ParseActionType type,
                             size_t state_index,
                             Symbol symbol,
                             size_t consumed_symbol_count,
                             set<int> precedence_values) :
        type(type),
        symbol(symbol),
        state_index(state_index),
        consumed_symbol_count(consumed_symbol_count),
        precedence_values(precedence_values) {}

    ParseAction::ParseAction() :
        type(ParseActionTypeError),
        symbol(Symbol(-1)),
        state_index(-1),
        consumed_symbol_count(0) {}

    ParseAction ParseAction::Error() {
        return ParseAction(ParseActionTypeError, -1, Symbol(-1), 0, { 0 });
    }

    ParseAction ParseAction::Accept() {
        return ParseAction(ParseActionTypeAccept, -1, Symbol(-1), 0, { 0 });
    }

    ParseAction ParseAction::Shift(size_t state_index, set<int> precedence_values) {
        return ParseAction(ParseActionTypeShift, state_index, Symbol(-1), 0, precedence_values);
    }

    ParseAction ParseAction::ShiftExtra() {
        return ParseAction(ParseActionTypeShiftExtra, -1, Symbol(-1), 0, { 0 });
    }

    ParseAction ParseAction::ReduceExtra(Symbol symbol) {
        return ParseAction(ParseActionTypeReduceExtra, -1, symbol, 0, { 0 });
    }

    ParseAction ParseAction::Reduce(Symbol symbol, size_t consumed_symbol_count, int precedence) {
        return ParseAction(ParseActionTypeReduce, -1, symbol, consumed_symbol_count, { precedence });
    }

    bool ParseAction::operator==(const ParseAction &other) const {
        bool types_eq = type == other.type;
        bool symbols_eq = symbol == other.symbol;
        bool state_indices_eq = state_index == other.state_index;
        bool consumed_symbol_counts_eq = consumed_symbol_count == other.consumed_symbol_count;
        return types_eq && symbols_eq && state_indices_eq && consumed_symbol_counts_eq;
    }

    ostream& operator<<(ostream &stream, const ParseAction &action) {
        switch (action.type) {
            case ParseActionTypeError:
                return stream << string("#<error>");
            case ParseActionTypeAccept:
                return stream << string("#<accept>");
            case ParseActionTypeShift:
                return stream << (string("#<shift ") + to_string(action.state_index) + ">");
            case ParseActionTypeShiftExtra:
                return stream << string("#<shift_extra");
            case ParseActionTypeReduce:
                return stream << (string("#<reduce sym") + to_string(action.symbol.index) + " " + to_string(action.consumed_symbol_count) + ">");
            default:
                return stream;
        }
    }

    ParseState::ParseState() : lex_state_id(-1) {}

    set<Symbol> ParseState::expected_inputs() const {
        set<Symbol> result;
        for (auto &pair : actions)
            result.insert(pair.first);
        return result;
    }

    ostream& operator<<(ostream &stream, const ParseState &state) {
        stream << string("#<parse_state ");
        bool started = false;
        for (auto pair : state.actions) {
            if (started) stream << string(", ");
            stream << pair.first << string(" => ") << pair.second;
            started = true;
        }
        stream << string(">");
        return stream;
    }

    ParseStateId ParseTable::add_state() {
        states.push_back(ParseState());
        return states.size() - 1;
    }

    void ParseTable::add_action(ParseStateId id, Symbol symbol, ParseAction action) {
        symbols.insert(symbol);
        states[id].actions[symbol] = action;
    }
}
<commit_msg>Fix stream operator for new parse action types<commit_after>#include "compiler/parse_table.h"
#include <string>

namespace tree_sitter {
    using std::string;
    using std::ostream;
    using std::to_string;
    using std::set;
    using std::vector;
    using rules::Symbol;

    ParseAction::ParseAction(ParseActionType type,
                             size_t state_index,
                             Symbol symbol,
                             size_t consumed_symbol_count,
                             set<int> precedence_values) :
        type(type),
        symbol(symbol),
        state_index(state_index),
        consumed_symbol_count(consumed_symbol_count),
        precedence_values(precedence_values) {}

    ParseAction::ParseAction() :
        type(ParseActionTypeError),
        symbol(Symbol(-1)),
        state_index(-1),
        consumed_symbol_count(0) {}

    ParseAction ParseAction::Error() {
        return ParseAction(ParseActionTypeError, -1, Symbol(-1), 0, { 0 });
    }

    ParseAction ParseAction::Accept() {
        return ParseAction(ParseActionTypeAccept, -1, Symbol(-1), 0, { 0 });
    }

    ParseAction ParseAction::Shift(size_t state_index, set<int> precedence_values) {
        return ParseAction(ParseActionTypeShift, state_index, Symbol(-1), 0, precedence_values);
    }

    ParseAction ParseAction::ShiftExtra() {
        return ParseAction(ParseActionTypeShiftExtra, -1, Symbol(-1), 0, { 0 });
    }

    ParseAction ParseAction::ReduceExtra(Symbol symbol) {
        return ParseAction(ParseActionTypeReduceExtra, -1, symbol, 0, { 0 });
    }

    ParseAction ParseAction::Reduce(Symbol symbol, size_t consumed_symbol_count, int precedence) {
        return ParseAction(ParseActionTypeReduce, -1, symbol, consumed_symbol_count, { precedence });
    }

    bool ParseAction::operator==(const ParseAction &other) const {
        bool types_eq = type == other.type;
        bool symbols_eq = symbol == other.symbol;
        bool state_indices_eq = state_index == other.state_index;
        bool consumed_symbol_counts_eq = consumed_symbol_count == other.consumed_symbol_count;
        return types_eq && symbols_eq && state_indices_eq && consumed_symbol_counts_eq;
    }

    ostream& operator<<(ostream &stream, const ParseAction &action) {
        switch (action.type) {
            case ParseActionTypeError:
                return stream << string("#<error>");
            case ParseActionTypeAccept:
                return stream << string("#<accept>");
            case ParseActionTypeShift:
                return stream << (string("#<shift ") + to_string(action.state_index) + ">");
            case ParseActionTypeShiftExtra:
                return stream << string("#<shift_extra");
            case ParseActionTypeReduceExtra:
                return stream << ("#<reduce_extra sym" + to_string(action.symbol.index) + ">");
            case ParseActionTypeReduce:
                return stream << ("#<reduce sym" + to_string(action.symbol.index) + " " + to_string(action.consumed_symbol_count) + ">");
            default:
                return stream;
        }
    }

    ParseState::ParseState() : lex_state_id(-1) {}

    set<Symbol> ParseState::expected_inputs() const {
        set<Symbol> result;
        for (auto &pair : actions)
            result.insert(pair.first);
        return result;
    }

    ostream& operator<<(ostream &stream, const ParseState &state) {
        stream << string("#<parse_state ");
        bool started = false;
        for (auto pair : state.actions) {
            if (started) stream << string(", ");
            stream << pair.first << string(" => ") << pair.second;
            started = true;
        }
        stream << string(">");
        return stream;
    }

    ParseStateId ParseTable::add_state() {
        states.push_back(ParseState());
        return states.size() - 1;
    }

    void ParseTable::add_action(ParseStateId id, Symbol symbol, ParseAction action) {
        symbols.insert(symbol);
        states[id].actions[symbol] = action;
    }
}
<|endoftext|>


<commit_before>#include "common.th"

#define IRR_ADDR        rel(IRR) //-1
#define ISR_ADDR        rel(ISR) //-2
#define IMR_ADDR        rel(IMR) //-3
#define SAVE_ADDR(Idx)  reloff(SAVE_END,Idx) //-4 - Idx

// TODO rewrite save_registers() to reduce arithmetic on stack pointer (O is
// updated twice consecutively due to the pushall_() macro where if handwritten
// it could be updated only once)
#define get_interrupt_stack() \
    O   -> [SAVE_ADDR(0)]   ; \
    O   <- SAVE_ADDR(1)     ; \
    //

#define restore_user_stack()  \
    O   <- [SAVE_ADDR(0)]   ; \
    //

.global irq_handler
irq_handler:
    get_interrupt_stack()
    pushall(C,B,D)

    B   <- [ISR_ADDR]

    // get lowest set bit in B
    C   <- B - 1
    C   <- B ^ C
    B   <- B & C

    D   <- 0            // base, for checking 8 bits at a time
    goto(check8)

top8:
    D   <- C & 1 + D
    B   <- B >> 8
check8:
    C   <- B & 0xff     // 0000000011111111
    C   <- C == A
    jnzrel(C,top8)

ready8:
    C   <- B & 0x0f     // 00001111
    C   <- C <> A + 1
    C   <- D << 1 + C

    D   <- B & 0x33     // 00110011
    D   <- D <> A + 1
    D   <- C << 1 + D

    C   <- B & 0x55     // 01010101
    C   <- C <> A + 1
    D   <- D << 1 + C

    // now D has the bit index of the lowest set bit in B
    C   <- [D + rel(irqtable)]

    popall(B,D)
    push(rel(after))
    // At vector dispatch, only O and C are saved. O is usable as the vector's
    // stack pointer ; C is the vector number and can be used as scratch.
    P   <- offsetpc(C)

after:
    popall(C)
    restore_user_stack()
    P   <- [IRR_ADDR]

// The IRR is written by the CPU, before irq_handler is called, with the address
// of the next userspace PC to be executed
IRR: .word @abort + 0x1000 // XXX hand-relocated address
ISR: .word -1 << 7
IMR: .word -1

SAVE: .word 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
SAVE_END:

irq_unhandled: .word 0x00ffdead ; illegal

.set irq00, @irq_unhandled ; .set irq01, @irq_unhandled ;
.set irq02, @irq_unhandled ; .set irq03, @irq_unhandled ;
.set irq04, @irq_unhandled ; .set irq05, @irq_unhandled ;
.set irq06, @irq_unhandled ; .set irq07, @irq_unhandled ;
.set irq08, @irq_unhandled ; .set irq09, @irq_unhandled ;
.set irq10, @irq_unhandled ; .set irq11, @irq_unhandled ;
.set irq12, @irq_unhandled ; .set irq13, @irq_unhandled ;
.set irq14, @irq_unhandled ; .set irq15, @irq_unhandled ;
.set irq16, @irq_unhandled ; .set irq17, @irq_unhandled ;
.set irq18, @irq_unhandled ; .set irq19, @irq_unhandled ;
.set irq20, @irq_unhandled ; .set irq21, @irq_unhandled ;
.set irq22, @irq_unhandled ; .set irq23, @irq_unhandled ;
.set irq24, @irq_unhandled ; .set irq25, @irq_unhandled ;
.set irq26, @irq_unhandled ; .set irq27, @irq_unhandled ;
.set irq28, @irq_unhandled ; .set irq29, @irq_unhandled ;
.set irq30, @irq_unhandled ; .set irq31, @irq_unhandled ;

.global irq00 ; .global irq01 ; .global irq02 ; .global irq03 ;
.global irq04 ; .global irq05 ; .global irq06 ; .global irq07 ;
.global irq08 ; .global irq09 ; .global irq10 ; .global irq11 ;
.global irq12 ; .global irq13 ; .global irq14 ; .global irq15 ;
.global irq16 ; .global irq17 ; .global irq18 ; .global irq19 ;
.global irq20 ; .global irq21 ; .global irq22 ; .global irq23 ;
.global irq24 ; .global irq25 ; .global irq26 ; .global irq27 ;
.global irq28 ; .global irq29 ; .global irq30 ; .global irq31 ;

irq07: .word  7; ret

irqtable:
    .word @irq00, @irq01, @irq02, @irq03, @irq04, @irq05, @irq06, @irq07,
          @irq08, @irq09, @irq10, @irq11, @irq12, @irq13, @irq14, @irq15,
          @irq16, @irq17, @irq18, @irq19, @irq20, @irq21, @irq22, @irq23,
          @irq24, @irq25, @irq26, @irq27, @irq28, @irq29, @irq30, @irq31

abort: .word 0x00aadead; illegal
<commit_msg>Explain changes needed for non-PIC vectors<commit_after>#include "common.th"

#define IRR_ADDR        rel(IRR) //-1
#define ISR_ADDR        rel(ISR) //-2
#define IMR_ADDR        rel(IMR) //-3
#define SAVE_ADDR(Idx)  reloff(SAVE_END,Idx) //-4 - Idx

// TODO rewrite save_registers() to reduce arithmetic on stack pointer (O is
// updated twice consecutively due to the pushall_() macro where if handwritten
// it could be updated only once)
#define get_interrupt_stack() \
    O   -> [SAVE_ADDR(0)]   ; \
    O   <- SAVE_ADDR(1)     ; \
    //

#define restore_user_stack()  \
    O   <- [SAVE_ADDR(0)]   ; \
    //

.global irq_handler
irq_handler:
    get_interrupt_stack()
    pushall(C,B,D)

    B   <- [ISR_ADDR]

    // get lowest set bit in B
    C   <- B - 1
    C   <- B ^ C
    B   <- B & C

    D   <- 0            // base, for checking 8 bits at a time
    goto(check8)

top8:
    D   <- C & 1 + D
    B   <- B >> 8
check8:
    C   <- B & 0xff     // 0000000011111111
    C   <- C == A
    jnzrel(C,top8)

ready8:
    C   <- B & 0x0f     // 00001111
    C   <- C <> A + 1
    C   <- D << 1 + C

    D   <- B & 0x33     // 00110011
    D   <- D <> A + 1
    D   <- C << 1 + D

    C   <- B & 0x55     // 01010101
    C   <- C <> A + 1
    C   <- D << 1 + C

    popall(B,D)
    push(rel(after))
    // now C has the bit index of the lowest set bit in B
    C   <- [C + rel(irqtable)]
    // At vector dispatch, only O and C are saved. O is usable as the vector's
    // stack pointer ; C is the vector number and can be used as scratch.
    // XXX C does not contain the vector number as it should !
    // This is because we are using position-independent code, when in the case
    // of the real vector table, both the table itself and its contents will be
    // effectively relocated (their addresses will be fixed in high memory).
    // Thus we will be able to turn load-jump instruction pair into a single
    // load-jump instruction. TODO support an .org or similar directive to put
    // things at known addresses.
    P   <- offsetpc(C)

after:
    popall(C)
    restore_user_stack()
    P   <- [IRR_ADDR]

// The IRR is written by the CPU, before irq_handler is called, with the address
// of the next userspace PC to be executed
IRR: .word @abort + 0x1000 // XXX hand-relocated address
ISR: .word -1 << 7
IMR: .word -1

SAVE: .word 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
SAVE_END:

irq_unhandled: .word 0x00ffdead ; illegal

.set irq00, @irq_unhandled ; .set irq01, @irq_unhandled ;
.set irq02, @irq_unhandled ; .set irq03, @irq_unhandled ;
.set irq04, @irq_unhandled ; .set irq05, @irq_unhandled ;
.set irq06, @irq_unhandled ; .set irq07, @irq_unhandled ;
.set irq08, @irq_unhandled ; .set irq09, @irq_unhandled ;
.set irq10, @irq_unhandled ; .set irq11, @irq_unhandled ;
.set irq12, @irq_unhandled ; .set irq13, @irq_unhandled ;
.set irq14, @irq_unhandled ; .set irq15, @irq_unhandled ;
.set irq16, @irq_unhandled ; .set irq17, @irq_unhandled ;
.set irq18, @irq_unhandled ; .set irq19, @irq_unhandled ;
.set irq20, @irq_unhandled ; .set irq21, @irq_unhandled ;
.set irq22, @irq_unhandled ; .set irq23, @irq_unhandled ;
.set irq24, @irq_unhandled ; .set irq25, @irq_unhandled ;
.set irq26, @irq_unhandled ; .set irq27, @irq_unhandled ;
.set irq28, @irq_unhandled ; .set irq29, @irq_unhandled ;
.set irq30, @irq_unhandled ; .set irq31, @irq_unhandled ;

.global irq00 ; .global irq01 ; .global irq02 ; .global irq03 ;
.global irq04 ; .global irq05 ; .global irq06 ; .global irq07 ;
.global irq08 ; .global irq09 ; .global irq10 ; .global irq11 ;
.global irq12 ; .global irq13 ; .global irq14 ; .global irq15 ;
.global irq16 ; .global irq17 ; .global irq18 ; .global irq19 ;
.global irq20 ; .global irq21 ; .global irq22 ; .global irq23 ;
.global irq24 ; .global irq25 ; .global irq26 ; .global irq27 ;
.global irq28 ; .global irq29 ; .global irq30 ; .global irq31 ;

irq07: .word  7; ret

irqtable:
    .word @irq00, @irq01, @irq02, @irq03, @irq04, @irq05, @irq06, @irq07,
          @irq08, @irq09, @irq10, @irq11, @irq12, @irq13, @irq14, @irq15,
          @irq16, @irq17, @irq18, @irq19, @irq20, @irq21, @irq22, @irq23,
          @irq24, @irq25, @irq26, @irq27, @irq28, @irq29, @irq30, @irq31

abort: .word 0x00aadead; illegal
<|endoftext|>