<commit_before>/*************************************************
* CAST-128 Source File                           *
* (C) 1999-2006 The Botan Project                *
*************************************************/

#include <botan/cast128.h>
#include <botan/bit_ops.h>

namespace Botan {

namespace {

/*************************************************
* CAST-128 Round Type 1                          *
*************************************************/
inline void R1(u32bit& L, u32bit R, u32bit MK, u32bit RK)
   {
   u32bit T = rotate_left(MK + R, RK);
   L ^= (CAST_SBOX1[get_byte(0, T)] ^ CAST_SBOX2[get_byte(1, T)]) -
         CAST_SBOX3[get_byte(2, T)] + CAST_SBOX4[get_byte(3, T)];
   }

/*************************************************
* CAST-128 Round Type 2                          *
*************************************************/
inline void R2(u32bit& L, u32bit R, u32bit MK, u32bit RK)
   {
   u32bit T = rotate_left(MK ^ R, RK);
   L ^= (CAST_SBOX1[get_byte(0, T)]  - CAST_SBOX2[get_byte(1, T)] +
         CAST_SBOX3[get_byte(2, T)]) ^ CAST_SBOX4[get_byte(3, T)];
   }

/*************************************************
* CAST-128 Round Type 3                          *
*************************************************/
inline void R3(u32bit& L, u32bit R, u32bit MK, u32bit RK)
   {
   u32bit T = rotate_left(MK - R, RK);
   L ^= ((CAST_SBOX1[get_byte(0, T)]  + CAST_SBOX2[get_byte(1, T)]) ^
          CAST_SBOX3[get_byte(2, T)]) - CAST_SBOX4[get_byte(3, T)];
   }

}

/*************************************************
* CAST-128 Encryption                            *
*************************************************/
void CAST_128::enc(const byte in[], byte out[]) const
   {
   u32bit L = make_u32bit(in[0], in[1], in[2], in[3]),
          R = make_u32bit(in[4], in[5], in[6], in[7]);

   R1(L, R, MK[ 0], RK[ 0]);
   R2(R, L, MK[ 1], RK[ 1]);
   R3(L, R, MK[ 2], RK[ 2]);
   R1(R, L, MK[ 3], RK[ 3]);
   R2(L, R, MK[ 4], RK[ 4]);
   R3(R, L, MK[ 5], RK[ 5]);
   R1(L, R, MK[ 6], RK[ 6]);
   R2(R, L, MK[ 7], RK[ 7]);
   R3(L, R, MK[ 8], RK[ 8]);
   R1(R, L, MK[ 9], RK[ 9]);
   R2(L, R, MK[10], RK[10]);
   R3(R, L, MK[11], RK[11]);
   R1(L, R, MK[12], RK[12]);
   R2(R, L, MK[13], RK[13]);
   R3(L, R, MK[14], RK[14]);
   R1(R, L, MK[15], RK[15]);

   out[0] = get_byte(0, R); out[1] = get_byte(1, R);
   out[2] = get_byte(2, R); out[3] = get_byte(3, R);
   out[4] = get_byte(0, L); out[5] = get_byte(1, L);
   out[6] = get_byte(2, L); out[7] = get_byte(3, L);
   }

/*************************************************
* CAST-128 Decryption                            *
*************************************************/
void CAST_128::dec(const byte in[], byte out[]) const
   {
   u32bit L = make_u32bit(in[0], in[1], in[2], in[3]),
          R = make_u32bit(in[4], in[5], in[6], in[7]);

   R1(L, R, MK[15], RK[15]);
   R3(R, L, MK[14], RK[14]);
   R2(L, R, MK[13], RK[13]);
   R1(R, L, MK[12], RK[12]);
   R3(L, R, MK[11], RK[11]);
   R2(R, L, MK[10], RK[10]);
   R1(L, R, MK[ 9], RK[ 9]);
   R3(R, L, MK[ 8], RK[ 8]);
   R2(L, R, MK[ 7], RK[ 7]);
   R1(R, L, MK[ 6], RK[ 6]);
   R3(L, R, MK[ 5], RK[ 5]);
   R2(R, L, MK[ 4], RK[ 4]);
   R1(L, R, MK[ 3], RK[ 3]);
   R3(R, L, MK[ 2], RK[ 2]);
   R2(L, R, MK[ 1], RK[ 1]);
   R1(R, L, MK[ 0], RK[ 0]);

   out[0] = get_byte(0, R); out[1] = get_byte(1, R);
   out[2] = get_byte(2, R); out[3] = get_byte(3, R);
   out[4] = get_byte(0, L); out[5] = get_byte(1, L);
   out[6] = get_byte(2, L); out[7] = get_byte(3, L);
   }

/*************************************************
* CAST-128 Key Schedule                          *
*************************************************/
void CAST_128::key(const byte key[], u32bit length)
   {
   clear();
   SecureBuffer<u32bit, 4> X;
   for(u32bit j = 0; j != length; ++j)
      X[j/4] = (X[j/4] << 8) + key[j];

   key_schedule(MK, X);
   key_schedule(RK, X);

   for(u32bit j = 0; j != 16; ++j)
      RK[j] %= 32;
   }

/*************************************************
* S-Box Based Key Expansion                      *
*************************************************/
void CAST_128::key_schedule(u32bit K[16], u32bit X[4])
   {
   class ByteReader
      {
      public:
         byte operator()(u32bit i) { return (X[i/4] >> (8*(3 - (i%4)))); }
         ByteReader(u32bit* x) : X(x) {}
      private:
         u32bit* X;
      };

   SecureBuffer<u32bit, 4> Z;
   ByteReader x(X), z(Z);

   Z[0]  = X[0] ^ S5[x(13)] ^ S6[x(15)] ^ S7[x(12)] ^ S8[x(14)] ^ S7[x( 8)];
   Z[1]  = X[2] ^ S5[z( 0)] ^ S6[z( 2)] ^ S7[z( 1)] ^ S8[z( 3)] ^ S8[x(10)];
   Z[2]  = X[3] ^ S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S5[x( 9)];
   Z[3]  = X[1] ^ S5[z(10)] ^ S6[z( 9)] ^ S7[z(11)] ^ S8[z( 8)] ^ S6[x(11)];
   K[ 0] = S5[z( 8)] ^ S6[z( 9)] ^ S7[z( 7)] ^ S8[z( 6)] ^ S5[z( 2)];
   K[ 1] = S5[z(10)] ^ S6[z(11)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S6[z( 6)];
   K[ 2] = S5[z(12)] ^ S6[z(13)] ^ S7[z( 3)] ^ S8[z( 2)] ^ S7[z( 9)];
   K[ 3] = S5[z(14)] ^ S6[z(15)] ^ S7[z( 1)] ^ S8[z( 0)] ^ S8[z(12)];
   X[0]  = Z[2] ^ S5[z( 5)] ^ S6[z( 7)] ^ S7[z( 4)] ^ S8[z( 6)] ^ S7[z( 0)];
   X[1]  = Z[0] ^ S5[x( 0)] ^ S6[x( 2)] ^ S7[x( 1)] ^ S8[x( 3)] ^ S8[z( 2)];
   X[2]  = Z[1] ^ S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S5[z( 1)];
   X[3]  = Z[3] ^ S5[x(10)] ^ S6[x( 9)] ^ S7[x(11)] ^ S8[x( 8)] ^ S6[z( 3)];
   K[ 4] = S5[x( 3)] ^ S6[x( 2)] ^ S7[x(12)] ^ S8[x(13)] ^ S5[x( 8)];
   K[ 5] = S5[x( 1)] ^ S6[x( 0)] ^ S7[x(14)] ^ S8[x(15)] ^ S6[x(13)];
   K[ 6] = S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 8)] ^ S8[x( 9)] ^ S7[x( 3)];
   K[ 7] = S5[x( 5)] ^ S6[x( 4)] ^ S7[x(10)] ^ S8[x(11)] ^ S8[x( 7)];
   Z[0]  = X[0] ^ S5[x(13)] ^ S6[x(15)] ^ S7[x(12)] ^ S8[x(14)] ^ S7[x( 8)];
   Z[1]  = X[2] ^ S5[z( 0)] ^ S6[z( 2)] ^ S7[z( 1)] ^ S8[z( 3)] ^ S8[x(10)];
   Z[2]  = X[3] ^ S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S5[x( 9)];
   Z[3]  = X[1] ^ S5[z(10)] ^ S6[z( 9)] ^ S7[z(11)] ^ S8[z( 8)] ^ S6[x(11)];
   K[ 8] = S5[z( 3)] ^ S6[z( 2)] ^ S7[z(12)] ^ S8[z(13)] ^ S5[z( 9)];
   K[ 9] = S5[z( 1)] ^ S6[z( 0)] ^ S7[z(14)] ^ S8[z(15)] ^ S6[z(12)];
   K[10] = S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 8)] ^ S8[z( 9)] ^ S7[z( 2)];
   K[11] = S5[z( 5)] ^ S6[z( 4)] ^ S7[z(10)] ^ S8[z(11)] ^ S8[z( 6)];
   X[0]  = Z[2] ^ S5[z( 5)] ^ S6[z( 7)] ^ S7[z( 4)] ^ S8[z( 6)] ^ S7[z( 0)];
   X[1]  = Z[0] ^ S5[x( 0)] ^ S6[x( 2)] ^ S7[x( 1)] ^ S8[x( 3)] ^ S8[z( 2)];
   X[2]  = Z[1] ^ S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S5[z( 1)];
   X[3]  = Z[3] ^ S5[x(10)] ^ S6[x( 9)] ^ S7[x(11)] ^ S8[x( 8)] ^ S6[z( 3)];
   K[12] = S5[x( 8)] ^ S6[x( 9)] ^ S7[x( 7)] ^ S8[x( 6)] ^ S5[x( 3)];
   K[13] = S5[x(10)] ^ S6[x(11)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S6[x( 7)];
   K[14] = S5[x(12)] ^ S6[x(13)] ^ S7[x( 3)] ^ S8[x( 2)] ^ S7[x( 8)];
   K[15] = S5[x(14)] ^ S6[x(15)] ^ S7[x( 1)] ^ S8[x( 0)] ^ S8[x(13)];
   }

}
<commit_msg>Make the ByteReader class in CAST_128::key_schedule only manipulate const pointers, as it doesn't actually need write access to anything.<commit_after>/*************************************************
* CAST-128 Source File                           *
* (C) 1999-2006 The Botan Project                *
*************************************************/

#include <botan/cast128.h>
#include <botan/bit_ops.h>

namespace Botan {

namespace {

/*************************************************
* CAST-128 Round Type 1                          *
*************************************************/
inline void R1(u32bit& L, u32bit R, u32bit MK, u32bit RK)
   {
   u32bit T = rotate_left(MK + R, RK);
   L ^= (CAST_SBOX1[get_byte(0, T)] ^ CAST_SBOX2[get_byte(1, T)]) -
         CAST_SBOX3[get_byte(2, T)] + CAST_SBOX4[get_byte(3, T)];
   }

/*************************************************
* CAST-128 Round Type 2                          *
*************************************************/
inline void R2(u32bit& L, u32bit R, u32bit MK, u32bit RK)
   {
   u32bit T = rotate_left(MK ^ R, RK);
   L ^= (CAST_SBOX1[get_byte(0, T)]  - CAST_SBOX2[get_byte(1, T)] +
         CAST_SBOX3[get_byte(2, T)]) ^ CAST_SBOX4[get_byte(3, T)];
   }

/*************************************************
* CAST-128 Round Type 3                          *
*************************************************/
inline void R3(u32bit& L, u32bit R, u32bit MK, u32bit RK)
   {
   u32bit T = rotate_left(MK - R, RK);
   L ^= ((CAST_SBOX1[get_byte(0, T)]  + CAST_SBOX2[get_byte(1, T)]) ^
          CAST_SBOX3[get_byte(2, T)]) - CAST_SBOX4[get_byte(3, T)];
   }

}

/*************************************************
* CAST-128 Encryption                            *
*************************************************/
void CAST_128::enc(const byte in[], byte out[]) const
   {
   u32bit L = make_u32bit(in[0], in[1], in[2], in[3]),
          R = make_u32bit(in[4], in[5], in[6], in[7]);

   R1(L, R, MK[ 0], RK[ 0]);
   R2(R, L, MK[ 1], RK[ 1]);
   R3(L, R, MK[ 2], RK[ 2]);
   R1(R, L, MK[ 3], RK[ 3]);
   R2(L, R, MK[ 4], RK[ 4]);
   R3(R, L, MK[ 5], RK[ 5]);
   R1(L, R, MK[ 6], RK[ 6]);
   R2(R, L, MK[ 7], RK[ 7]);
   R3(L, R, MK[ 8], RK[ 8]);
   R1(R, L, MK[ 9], RK[ 9]);
   R2(L, R, MK[10], RK[10]);
   R3(R, L, MK[11], RK[11]);
   R1(L, R, MK[12], RK[12]);
   R2(R, L, MK[13], RK[13]);
   R3(L, R, MK[14], RK[14]);
   R1(R, L, MK[15], RK[15]);

   out[0] = get_byte(0, R); out[1] = get_byte(1, R);
   out[2] = get_byte(2, R); out[3] = get_byte(3, R);
   out[4] = get_byte(0, L); out[5] = get_byte(1, L);
   out[6] = get_byte(2, L); out[7] = get_byte(3, L);
   }

/*************************************************
* CAST-128 Decryption                            *
*************************************************/
void CAST_128::dec(const byte in[], byte out[]) const
   {
   u32bit L = make_u32bit(in[0], in[1], in[2], in[3]),
          R = make_u32bit(in[4], in[5], in[6], in[7]);

   R1(L, R, MK[15], RK[15]);
   R3(R, L, MK[14], RK[14]);
   R2(L, R, MK[13], RK[13]);
   R1(R, L, MK[12], RK[12]);
   R3(L, R, MK[11], RK[11]);
   R2(R, L, MK[10], RK[10]);
   R1(L, R, MK[ 9], RK[ 9]);
   R3(R, L, MK[ 8], RK[ 8]);
   R2(L, R, MK[ 7], RK[ 7]);
   R1(R, L, MK[ 6], RK[ 6]);
   R3(L, R, MK[ 5], RK[ 5]);
   R2(R, L, MK[ 4], RK[ 4]);
   R1(L, R, MK[ 3], RK[ 3]);
   R3(R, L, MK[ 2], RK[ 2]);
   R2(L, R, MK[ 1], RK[ 1]);
   R1(R, L, MK[ 0], RK[ 0]);

   out[0] = get_byte(0, R); out[1] = get_byte(1, R);
   out[2] = get_byte(2, R); out[3] = get_byte(3, R);
   out[4] = get_byte(0, L); out[5] = get_byte(1, L);
   out[6] = get_byte(2, L); out[7] = get_byte(3, L);
   }

/*************************************************
* CAST-128 Key Schedule                          *
*************************************************/
void CAST_128::key(const byte key[], u32bit length)
   {
   clear();
   SecureBuffer<u32bit, 4> X;
   for(u32bit j = 0; j != length; ++j)
      X[j/4] = (X[j/4] << 8) + key[j];

   key_schedule(MK, X);
   key_schedule(RK, X);

   for(u32bit j = 0; j != 16; ++j)
      RK[j] %= 32;
   }

/*************************************************
* S-Box Based Key Expansion                      *
*************************************************/
void CAST_128::key_schedule(u32bit K[16], u32bit X[4])
   {
   class ByteReader
      {
      public:
         byte operator()(u32bit i) { return (X[i/4] >> (8*(3 - (i%4)))); }
         ByteReader(const u32bit* x) : X(x) {}
      private:
         const u32bit* X;
      };

   SecureBuffer<u32bit, 4> Z;
   ByteReader x(X), z(Z);

   Z[0]  = X[0] ^ S5[x(13)] ^ S6[x(15)] ^ S7[x(12)] ^ S8[x(14)] ^ S7[x( 8)];
   Z[1]  = X[2] ^ S5[z( 0)] ^ S6[z( 2)] ^ S7[z( 1)] ^ S8[z( 3)] ^ S8[x(10)];
   Z[2]  = X[3] ^ S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S5[x( 9)];
   Z[3]  = X[1] ^ S5[z(10)] ^ S6[z( 9)] ^ S7[z(11)] ^ S8[z( 8)] ^ S6[x(11)];
   K[ 0] = S5[z( 8)] ^ S6[z( 9)] ^ S7[z( 7)] ^ S8[z( 6)] ^ S5[z( 2)];
   K[ 1] = S5[z(10)] ^ S6[z(11)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S6[z( 6)];
   K[ 2] = S5[z(12)] ^ S6[z(13)] ^ S7[z( 3)] ^ S8[z( 2)] ^ S7[z( 9)];
   K[ 3] = S5[z(14)] ^ S6[z(15)] ^ S7[z( 1)] ^ S8[z( 0)] ^ S8[z(12)];
   X[0]  = Z[2] ^ S5[z( 5)] ^ S6[z( 7)] ^ S7[z( 4)] ^ S8[z( 6)] ^ S7[z( 0)];
   X[1]  = Z[0] ^ S5[x( 0)] ^ S6[x( 2)] ^ S7[x( 1)] ^ S8[x( 3)] ^ S8[z( 2)];
   X[2]  = Z[1] ^ S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S5[z( 1)];
   X[3]  = Z[3] ^ S5[x(10)] ^ S6[x( 9)] ^ S7[x(11)] ^ S8[x( 8)] ^ S6[z( 3)];
   K[ 4] = S5[x( 3)] ^ S6[x( 2)] ^ S7[x(12)] ^ S8[x(13)] ^ S5[x( 8)];
   K[ 5] = S5[x( 1)] ^ S6[x( 0)] ^ S7[x(14)] ^ S8[x(15)] ^ S6[x(13)];
   K[ 6] = S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 8)] ^ S8[x( 9)] ^ S7[x( 3)];
   K[ 7] = S5[x( 5)] ^ S6[x( 4)] ^ S7[x(10)] ^ S8[x(11)] ^ S8[x( 7)];
   Z[0]  = X[0] ^ S5[x(13)] ^ S6[x(15)] ^ S7[x(12)] ^ S8[x(14)] ^ S7[x( 8)];
   Z[1]  = X[2] ^ S5[z( 0)] ^ S6[z( 2)] ^ S7[z( 1)] ^ S8[z( 3)] ^ S8[x(10)];
   Z[2]  = X[3] ^ S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S5[x( 9)];
   Z[3]  = X[1] ^ S5[z(10)] ^ S6[z( 9)] ^ S7[z(11)] ^ S8[z( 8)] ^ S6[x(11)];
   K[ 8] = S5[z( 3)] ^ S6[z( 2)] ^ S7[z(12)] ^ S8[z(13)] ^ S5[z( 9)];
   K[ 9] = S5[z( 1)] ^ S6[z( 0)] ^ S7[z(14)] ^ S8[z(15)] ^ S6[z(12)];
   K[10] = S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 8)] ^ S8[z( 9)] ^ S7[z( 2)];
   K[11] = S5[z( 5)] ^ S6[z( 4)] ^ S7[z(10)] ^ S8[z(11)] ^ S8[z( 6)];
   X[0]  = Z[2] ^ S5[z( 5)] ^ S6[z( 7)] ^ S7[z( 4)] ^ S8[z( 6)] ^ S7[z( 0)];
   X[1]  = Z[0] ^ S5[x( 0)] ^ S6[x( 2)] ^ S7[x( 1)] ^ S8[x( 3)] ^ S8[z( 2)];
   X[2]  = Z[1] ^ S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S5[z( 1)];
   X[3]  = Z[3] ^ S5[x(10)] ^ S6[x( 9)] ^ S7[x(11)] ^ S8[x( 8)] ^ S6[z( 3)];
   K[12] = S5[x( 8)] ^ S6[x( 9)] ^ S7[x( 7)] ^ S8[x( 6)] ^ S5[x( 3)];
   K[13] = S5[x(10)] ^ S6[x(11)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S6[x( 7)];
   K[14] = S5[x(12)] ^ S6[x(13)] ^ S7[x( 3)] ^ S8[x( 2)] ^ S7[x( 8)];
   K[15] = S5[x(14)] ^ S6[x(15)] ^ S7[x( 1)] ^ S8[x( 0)] ^ S8[x(13)];
   }

}
<|endoftext|>


<commit_before><commit_msg>Fix confusion about filetype of auto-corrected POTs<commit_after><|endoftext|>


<commit_before>/* cclive
 * Copyright (C) 2010-2013  Toni Gundogdu <legatvs@gmail.com>
 *
 * This file is part of cclive <http://cclive.sourceforge.net/>.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 */

#include <ccinternal>

#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception/errinfo_file_name.hpp>
#include <boost/exception/get_error_info.hpp>
#include <boost/exception/errinfo_errno.hpp>

#include <stdexcept>
#include <iostream>
#include <clocale>

#include <ccapplication>
#include <ccquvi>
#include <ccutil>

using namespace cc;

static application::exit_status print(const boost::exception& x)
{
  std::clog << "error: ";

  if (std::string const *s =
        boost::get_error_info<boost::errinfo_file_name>(x))
    {
      std::clog << *s << ": ";
    }

  bool have_strerror = false;
  if (int const *n =
        boost::get_error_info<boost::errinfo_errno>(x))
    {
      std::clog << cc::perror() << " (" << *n << ")";
      have_strerror = true;
    }

  try
    {
      throw;
    }
  catch (const std::exception& x)
    {
      if (!have_strerror)
        std::clog << x.what();
    }
  catch (...)
    {
      std::clog << boost::diagnostic_information(x);
    }
  std::clog << std::endl;

  return application::error;
}

int main(int argc, char *argv[])
{
  setlocale(LC_ALL, "");
  application::exit_status es = application::ok;
  application app;
  try
    {
      es = app.exec(argc, argv);
    }
  // Thrown by quvi::query constructor (e.g. quvi_init, quvi_new).
  catch (const quvi::error& e)
    {
      std::clog << "libquvi: error: " << e.what() << std::endl;
      es = application::error;
    }
  // Thrown by boost (e.g. cc::go_background failure).
  catch (const std::runtime_error& e)
    {
      std::clog << "error: " << e.what() << std::endl;
      es = application::error;
    }
  // Thrown by boost::program_options (cc::options).
  catch (const boost::exception& x)
    {
      es = print(x);
    }
  return es;
}

// vim: set ts=2 sw=2 tw=72 expandtab:
<commit_msg>main: Use cc::error, catch cc::options::exit_program<commit_after>/* cclive
 * Copyright (C) 2010-2013  Toni Gundogdu <legatvs@gmail.com>
 *
 * This file is part of cclive <http://cclive.sourceforge.net/>.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 */

#include <ccinternal>

#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception/errinfo_file_name.hpp>
#include <boost/exception/get_error_info.hpp>
#include <boost/exception/errinfo_errno.hpp>

#include <stdexcept>
#include <iostream>
#include <clocale>

#include <ccapplication>
#include <ccquvi>
#include <ccoptions>
#include <ccutil>

using namespace cc;

int main(int const argc, char const **argv)
{
  setlocale(LC_ALL, "");
  application::exit_status es = application::ok;
  application app;
  try
    {
      es = app.exec(argc, argv);
    }
  // --version, --help, etc.
  catch (const cc::options::exit_program&)
    {
      // Fall through.
    }
  // Thrown by quvi::query constructor (e.g. quvi_init, quvi_new).
  catch (const quvi::error& e)
    {
      std::clog << "libquvi: error: " << e.what() << std::endl;
      es = application::error;
    }
  // Thrown by boost (e.g. cc::go_background failure).
  catch (const std::runtime_error& e)
    {
      std::clog << "error: " << e.what() << std::endl;
      es = application::error;
    }
  // Thrown by boost::program_options (cc::options).
  catch (const boost::exception& x)
    {
      es = static_cast<application::exit_status>(cc::error::print(x));
    }
  return es;
}

// vim: set ts=2 sw=2 tw=72 expandtab:
<|endoftext|>


<commit_before>#include <stdio.h>
#include <string>
#include <regex>
#include <iostream>
#include <fstream>
#include <sstream>

#include <astar\AStar.h>

namespace han {
    namespace ap {
        namespace cli {
            enum arg_options {
                output_file,
                pretty_output
            };

            uint32_t find_arg_code(std::string arg_) {
                if (arg_ == "-o") return arg_options::output_file;
                if (arg_ == "-p") return arg_options::pretty_output;

                return -1;
            }
        }
    }
}

int main(int argc, char **argv) {
    uint32_t arg_index = 1;
    if (argc < 2) {
        std::cout << "Usage: cli.exe [-p] [-o output.sqf] input.sqf\n";
    //    return 0;
    }

    HAN::NodePtrs nodes;
    for (int i = 0; i <= 17; ++i) {
        for (int j = 0; j <= 17; ++j) {
            HAN::NodePtr node = std::shared_ptr<HAN::Node>(new HAN::Node(i, j));
            if (j == 1 && i < 5)
                node->accessable = false;

            nodes.push_back(node);
        }
    }
    HAN::Grid grid = HAN::Grid("My Grid name", nodes);

    HAN::AStar aStar = HAN::AStar(grid);

    HAN::NodePtr start = HAN::NodePtr(new HAN::Node(0, 0));
    HAN::NodePtr goal = HAN::NodePtr(new HAN::Node(10, 15));

    auto path = aStar.Calculate(start, goal);

    grid.print(path);

    return 0;
}
<commit_msg>Add better examples being printed in the cli<commit_after>#include <stdio.h>
#include <string>
#include <regex>
#include <iostream>
#include <fstream>
#include <sstream>

#include <astar\AStar.h>

namespace han {
    namespace ap {
        namespace cli {
            enum arg_options {
                output_file,
                pretty_output
            };

            uint32_t find_arg_code(std::string arg_) {
                if (arg_ == "-o") return arg_options::output_file;
                if (arg_ == "-p") return arg_options::pretty_output;

                return -1;
            }
        }
    }
}

int main(int argc, char **argv) {
    uint32_t arg_index = 1;
    if (argc < 2) {
        std::cout << "Usage: cli.exe [-p] [-o output.sqf] input.sqf\n";
    //    return 0;
    }

    HAN::NodePtrs nodes;
    for (int i = 0; i <= 30; ++i) {
        for (int j = 0; j <= 17; ++j) {
            HAN::NodePtr node = std::shared_ptr<HAN::Node>(new HAN::Node(i, j));
            if (j == 12 && i > 3 && i < 15)
                node->accessable = false;

            if (j == 5 && i > 2 && i < 15)
                node->accessable = false;

            if (i == 15 && j < 15)
                node->accessable = false;

            if (i == 20 && j > 10)
                node->accessable = false;
            nodes.push_back(node);
        }
    }
    HAN::Grid grid = HAN::Grid("My Grid name", nodes);

    HAN::AStar aStar = HAN::AStar(grid);

    HAN::NodePtr start = HAN::NodePtr(new HAN::Node(0, 0));
    HAN::NodePtr goal = HAN::NodePtr(new HAN::Node(27, 16));

    auto path = aStar.Calculate(start, goal);

    grid.print(path);

    grid.print(aStar.Calculate(HAN::NodePtr(new HAN::Node(0, 0)), HAN::NodePtr(new HAN::Node(25, 2))));
    grid.print(aStar.Calculate(HAN::NodePtr(new HAN::Node(10, 10)), HAN::NodePtr(new HAN::Node(0, 0))));
    grid.print(aStar.Calculate(HAN::NodePtr(new HAN::Node(14, 4)), HAN::NodePtr(new HAN::Node(0, 0))));

    aStar.SetHeuristic(7);
    grid.print(aStar.Calculate(HAN::NodePtr(new HAN::Node(14, 4)), HAN::NodePtr(new HAN::Node(0, 0))));

    return 0;
}
<|endoftext|>


<commit_before>#include "internal.hpp"

namespace CaDiCaL {

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

// Returns positive number 1 ( > 0) if the given clause is root level
// satisfied or the negative number -1 ( < 0) if it is not root level
// satisfied but contains a root level falsified literal and 0 otherwise, if
// it does not contain a root level fixed literal.

int Internal::clause_contains_fixed_literal (Clause * c) {
  const const_literal_iterator end = c->end ();
  const_literal_iterator i = c->begin ();
  int res = 0;
  while (res <= 0 && i != end) {
    const int lit = *i++, tmp = fixed (lit);
    if (tmp > 0) {
      LOG (c, "root level satisfied literal %d in", lit);
      res = 1;
    } else if (!res && tmp < 0) {
      LOG (c, "root level falsified literal %d in", lit);
      res = -1;
    }
  }
  return res;
}

// Assume that the clause is not root level satisfied but contains a literal
// set to false (root level falsified literal), so it can be shrunken.  The
// clause data is not actually reallocated at this point to avoid dealing
// with issues of special policies for watching binary clauses or whether a
// clause is extended or not. Only its size field is adjusted accordingly
// after flushing out root level falsified literals.

void Internal::remove_falsified_literals (Clause * c) {
  const const_literal_iterator end = c->end ();
  const_literal_iterator i;
  int num_non_false = 0;
  for (i = c->begin (); num_non_false < 2 && i != end; i++)
    if (fixed (*i) >= 0) num_non_false++;
  if (num_non_false < 2) return;
  if (proof) proof->trace_flushing_clause (c);
  literal_iterator j = c->begin ();
  for (i = j; i != end; i++) {
    const int lit = *j++ = *i, tmp = fixed (lit);
    assert (tmp <= 0);
    if (tmp >= 0) continue;
    LOG ("flushing %d", lit);
    j--;
  }
  stats.collected += shrink_clause_size (c, j - c->begin ());
  if (likely_to_be_kept_clause (c)) mark_added (c);
}

// If there are new units (fixed variables) since the last garbage
// collection we go over all clauses, mark satisfied ones as garbage and
// flush falsified literals.  Otherwise if no new units have been generated
// since the last garbage collection just skip this step.

void Internal::mark_satisfied_clauses_as_garbage () {

  if (lim.fixed_at_last_collect >= stats.all.fixed) return;
  lim.fixed_at_last_collect = stats.all.fixed;

  LOG ("marking satisfied clauses and removing falsified literals");

  const_clause_iterator i;
  for (i = clauses.begin (); i != clauses.end (); i++) {
    Clause * c = *i;
    if (c->garbage) continue;
    const int tmp = clause_contains_fixed_literal (c);
         if (tmp > 0) mark_garbage (c);
    else if (tmp < 0) remove_falsified_literals (c);
  }
}

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

// Update occurrence lists before deleting garbage clauses in the context of
// preprocessing, e.g., during bounded variable elimination 'elim'.  The
// result is the number of remaining clauses, which in this context  means
// the number of non-garbage clauses.

size_t Internal::flush_occs (int lit) {
  Occs & os = occs (lit);
  const const_occs_iterator end = os.end ();
  occs_iterator j = os.begin ();
  const_occs_iterator i;
  size_t res = 0;
  Clause * c;
  for (i = j; i != end; i++) {
    c = *i;
    if (c->collect ()) continue;
    *j++ = c->moved ? c->copy : c;
    assert (!c->redundant);
    res++;
  }
  os.resize (j - os.begin ());
  shrink_occs (os);
  return res;
}

// Update watch lists before deleting garbage clauses in the context of
// 'reduce' where we watch and no occurrence lists.  We have to protect
// reason clauses not be collected and thus we have this additional check
// hidden in 'Clause.collect', which for the root level context of
// preprocessing is actually redundant.

inline void Internal::flush_watches (int lit, Watches & saved) {
  assert (saved.empty ());
  Watches & ws = watches (lit);
  const_watch_iterator end = ws.end ();
  watch_iterator j = ws.begin ();
  const_watch_iterator i;
  for (i = j; i != end; i++) {
    Watch w = *i;
    Clause * c = w.clause;
    if (c->collect ()) continue;
    if (c->moved) c = w.clause = c->copy;
    if (c->size == 2 && !w.binary) w.binary = true;
    const int new_blit_pos = (c->literals[0] == lit);
    assert (c->literals[!new_blit_pos] == lit);
    w.blit = c->literals[new_blit_pos];
    if (w.binary) *j++ = w;
    else saved.push_back (w);
  }
  ws.resize (j - ws.begin ());
  end = saved.end ();
  for (i = saved.begin (); i != end; i++)
    ws.push_back (*i);
  saved.clear ();
  shrink_watches (ws);
}

void Internal::flush_all_occs_and_watches () {
  if (occs ())
    for (int idx = 1; idx <= max_var; idx++)
      flush_occs (idx), flush_occs (-idx);

  if (watches ()) {
    Watches tmp;
    for (int idx = 1; idx <= max_var; idx++)
      flush_watches (idx, tmp), flush_watches (-idx, tmp);
  }
}

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

// This is a simple garbage collector which does not move clauses.  It needs
// less space than the arena based clause allocator, but is not as cache
// efficient, since the copying garbage collector can put clauses together
// which are likely accessed after each other.

void Internal::delete_garbage_clauses () {

  flush_all_occs_and_watches ();

  LOG ("deleting garbage clauses");
  long collected_bytes = 0, collected_clauses = 0;
  const const_clause_iterator end = clauses.end ();
  clause_iterator j = clauses.begin ();
  const_clause_iterator i = j;
  while (i != end) {
    Clause * c = *j++ = *i++;
    if (!c->collect ()) continue;
    collected_bytes += c->bytes ();
    collected_clauses++;
    delete_clause (c);
    j--;
  }
  clauses.resize (j - clauses.begin ());
  shrink_vector (clauses);

  VRB ("collect", stats.collections,
    "collected %ld bytes of %ld garbage clauses",
    collected_bytes, collected_clauses);
}

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

// This is the start of the copying garbage collector using the arena.  At
// the core is the following function, which copies a clause to the 'to'
// space of the arena.  Be careful if this clause is a reason of an
// assignment.  In that case update the reason reference.
//
void Internal::copy_clause (Clause * c) {
  LOG (c, "moving");
  assert (!c->moved);
  char * p = c->start (), * q = arena.copy (p, c->bytes ());
  assert (aligned (q, 8));
  Clause * d = c->copy = (Clause *) (q - c->offset ());
  if (d->reason) var (d->literals[val (d->literals[1]) > 0]).reason = d;
  c->moved = true;
}

// This is the moving garbage collector.

void Internal::copy_non_garbage_clauses () {

  Clause * c;

  size_t collected_clauses = 0, collected_bytes = 0;
  size_t     moved_clauses = 0,     moved_bytes = 0;

  // First determine 'moved_bytes' and 'collected_bytes'.
  //
  const const_clause_iterator end = clauses.end ();
  const_clause_iterator i;
  for (i = clauses.begin (); i != end; i++)
    if (!(c = *i)->collect ()) moved_bytes += c->bytes (), moved_clauses++;
    else collected_bytes += c->bytes (), collected_clauses++;

  VRB ("collect", stats.collections,
    "moving %ld bytes %.0f%% of %ld non garbage clauses",
    (long) moved_bytes,
    percent (moved_bytes, collected_bytes + moved_bytes),
    (long) moved_clauses);

  // Prepare 'to' space of size 'moved_bytes'.
  //
  arena.prepare (moved_bytes);

  if (opts.arena == 1 || !watches ()) {

    // Localize according to current clause order.

    // If the option 'opts.arena == 1' is set, then this means the solver
    // uses the original order of clauses.  If there are no watches, we can
    // not use the watched based copying policies below.  This happens if
    // garbage collection is triggered during bounded variable elimination.

    // Copy clauses according to the order of calling 'copy_clause', which
    // in essence just gives a compacting garbage collector, since their
    // relative order is kept, and actually already gives the largest
    // benefit due to better cache locality.

    for (i = clauses.begin (); i != end; i++)
      if (!(c = *i)->collect ()) copy_clause (c);

  } else if (opts.arena == 2) {

    // Localize according to (original) variable order.

    // This is almost the version used by MiniSAT and descendants and seems
    // to work best for search.  Our version uses saved phases.

    for (int sign = -1; sign <= 1; sign += 2) {
      for (int idx = 1; idx <= max_var; idx++) {
        const Watches & ws = watches (sign * phases[idx] * idx);
        const const_watch_iterator ew = ws.end ();
        for (const_watch_iterator i = ws.begin (); i != ew; i++)
          if (!(c = i->clause)->moved && !c->collect ()) copy_clause (c);
      }
    }

  } else {

    // Localize according to decision queue order.

    // This is second best for search. It allocates clauses in the order of
    // the decision queue.  It also uses saved phases.  Intuitively it
    // should be faster than MiniSAT version, but it seems that using the
    // original variable order ('opts.arena==2') gives a small benefit.

    assert (opts.arena == 3);

    for (int sign = -1; sign <= 1; sign += 2) {
      for (int idx = queue.last; idx; idx = link (idx).prev) {
        const Watches & ws = watches (sign * phases[idx] * idx);
        const const_watch_iterator ew = ws.end ();
        for (const_watch_iterator i = ws.begin (); i != ew; i++)
          if (!(c = i->clause)->moved && !c->collect ()) copy_clause (c);
      }
    }
  }

  // Do not forget to move clauses which are not watched, which happened in
  // a rare situation, and now is only left as defensive code.
  //
  for (i = clauses.begin (); i != end; i++)
    if (!(c = *i)->collect () && !c->moved) copy_clause (c);

  // Updates watches or occurrence lists.
  //
  flush_all_occs_and_watches ();

  // Replace and flush clause references in 'clauses'.
  //
  clause_iterator j = clauses.begin ();
  assert (end == clauses.end ());
  for (i = j; i != end; i++) {
    if ((c = *i)->collect ()) delete_clause (c);
    else assert (c->moved), *j++ = c->copy, deallocate_clause (c);
  }
  clauses.resize (j - clauses.begin ());
  if (clauses.size () < clauses.capacity ()/2) shrink_vector (clauses);

  // Replace and flush references in the vivification schedule.

  // Release 'from' space completely and then swap 'to' with 'from'.
  //
  arena.swap ();

  VRB ("collect", stats.collections,
    "collected %ld bytes %.0f%% of %ld garbage clauses",
    (long) collected_bytes,
    percent (collected_bytes, collected_bytes + moved_bytes),
    (long) collected_clauses);
}

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

// Maintaining clause statistics is complex and error prone but necessary
// for proper scheduling of garbage collection, particularly during bounded
// variable elimination.  With this function we can check whether these
// statistics are updated correctly.

void Internal::check_clause_stats () {
#ifndef NDEBUG
  long irredundant = 0, redundant = 0, irrbytes = 0;
  const const_clause_iterator end = clauses.end ();
  const_clause_iterator i;
  for (i = clauses.begin (); i != end; i++) {
    Clause * c = *i;
    if (c->garbage) continue;
    if (c->redundant) redundant++; else irredundant++;
    if (!c->redundant) irrbytes += c->bytes ();
  }
  assert (stats.irredundant == irredundant);
  assert (stats.redundant == redundant);
  assert (stats.irrbytes == irrbytes);
#endif
}

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

bool Internal::arenaing () {
  return opts.arena && (stats.collections > 1);  // TODO more sophisticated
}

void Internal::garbage_collection () {
  if (unsat) return;
  START (collect);
  report ('G', 1);
  stats.collections++;
  mark_satisfied_clauses_as_garbage ();
  if (arenaing ()) copy_non_garbage_clauses ();
  else delete_garbage_clauses ();
  check_clause_stats ();
  check_var_stats ();
  report ('C', 1);
  STOP (collect);
}

};
<commit_msg>fixed comments<commit_after>#include "internal.hpp"

namespace CaDiCaL {

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

// Returns positive number 1 ( > 0) if the given clause is root level
// satisfied or the negative number -1 ( < 0) if it is not root level
// satisfied but contains a root level falsified literal and 0 otherwise, if
// it does not contain a root level fixed literal.

int Internal::clause_contains_fixed_literal (Clause * c) {
  const const_literal_iterator end = c->end ();
  const_literal_iterator i = c->begin ();
  int res = 0;
  while (res <= 0 && i != end) {
    const int lit = *i++, tmp = fixed (lit);
    if (tmp > 0) {
      LOG (c, "root level satisfied literal %d in", lit);
      res = 1;
    } else if (!res && tmp < 0) {
      LOG (c, "root level falsified literal %d in", lit);
      res = -1;
    }
  }
  return res;
}

// Assume that the clause is not root level satisfied but contains a literal
// set to false (root level falsified literal), so it can be shrunken.  The
// clause data is not actually reallocated at this point to avoid dealing
// with issues of special policies for watching binary clauses or whether a
// clause is extended or not. Only its size field is adjusted accordingly
// after flushing out root level falsified literals.

void Internal::remove_falsified_literals (Clause * c) {
  const const_literal_iterator end = c->end ();
  const_literal_iterator i;
  int num_non_false = 0;
  for (i = c->begin (); num_non_false < 2 && i != end; i++)
    if (fixed (*i) >= 0) num_non_false++;
  if (num_non_false < 2) return;
  if (proof) proof->trace_flushing_clause (c);
  literal_iterator j = c->begin ();
  for (i = j; i != end; i++) {
    const int lit = *j++ = *i, tmp = fixed (lit);
    assert (tmp <= 0);
    if (tmp >= 0) continue;
    LOG ("flushing %d", lit);
    j--;
  }
  stats.collected += shrink_clause_size (c, j - c->begin ());
  if (likely_to_be_kept_clause (c)) mark_added (c);
}

// If there are new units (fixed variables) since the last garbage
// collection we go over all clauses, mark satisfied ones as garbage and
// flush falsified literals.  Otherwise if no new units have been generated
// since the last garbage collection just skip this step.

void Internal::mark_satisfied_clauses_as_garbage () {

  if (lim.fixed_at_last_collect >= stats.all.fixed) return;
  lim.fixed_at_last_collect = stats.all.fixed;

  LOG ("marking satisfied clauses and removing falsified literals");

  const_clause_iterator i;
  for (i = clauses.begin (); i != clauses.end (); i++) {
    Clause * c = *i;
    if (c->garbage) continue;
    const int tmp = clause_contains_fixed_literal (c);
         if (tmp > 0) mark_garbage (c);
    else if (tmp < 0) remove_falsified_literals (c);
  }
}

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

// Update occurrence lists before deleting garbage clauses in the context of
// preprocessing, e.g., during bounded variable elimination 'elim'.  The
// result is the number of remaining clauses, which in this context  means
// the number of non-garbage clauses.

size_t Internal::flush_occs (int lit) {
  Occs & os = occs (lit);
  const const_occs_iterator end = os.end ();
  occs_iterator j = os.begin ();
  const_occs_iterator i;
  size_t res = 0;
  Clause * c;
  for (i = j; i != end; i++) {
    c = *i;
    if (c->collect ()) continue;
    *j++ = c->moved ? c->copy : c;
    assert (!c->redundant);
    res++;
  }
  os.resize (j - os.begin ());
  shrink_occs (os);
  return res;
}

// Update watch lists before deleting garbage clauses in the context of
// 'reduce' where we watch and no occurrence lists.  We have to protect
// reason clauses not be collected and thus we have this additional check
// hidden in 'Clause.collect', which for the root level context of
// preprocessing is actually redundant.

inline void Internal::flush_watches (int lit, Watches & saved) {
  assert (saved.empty ());
  Watches & ws = watches (lit);
  const_watch_iterator end = ws.end ();
  watch_iterator j = ws.begin ();
  const_watch_iterator i;
  for (i = j; i != end; i++) {
    Watch w = *i;
    Clause * c = w.clause;
    if (c->collect ()) continue;
    if (c->moved) c = w.clause = c->copy;
    if (c->size == 2 && !w.binary) w.binary = true;
    const int new_blit_pos = (c->literals[0] == lit);
    assert (c->literals[!new_blit_pos] == lit);
    w.blit = c->literals[new_blit_pos];
    if (w.binary) *j++ = w;
    else saved.push_back (w);
  }
  ws.resize (j - ws.begin ());
  end = saved.end ();
  for (i = saved.begin (); i != end; i++)
    ws.push_back (*i);
  saved.clear ();
  shrink_watches (ws);
}

void Internal::flush_all_occs_and_watches () {
  if (occs ())
    for (int idx = 1; idx <= max_var; idx++)
      flush_occs (idx), flush_occs (-idx);

  if (watches ()) {
    Watches tmp;
    for (int idx = 1; idx <= max_var; idx++)
      flush_watches (idx, tmp), flush_watches (-idx, tmp);
  }
}

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

// This is a simple garbage collector which does not move clauses.  It needs
// less space than the arena based clause allocator, but is not as cache
// efficient, since the copying garbage collector can put clauses together
// which are likely accessed after each other.

void Internal::delete_garbage_clauses () {

  flush_all_occs_and_watches ();

  LOG ("deleting garbage clauses");
  long collected_bytes = 0, collected_clauses = 0;
  const const_clause_iterator end = clauses.end ();
  clause_iterator j = clauses.begin ();
  const_clause_iterator i = j;
  while (i != end) {
    Clause * c = *j++ = *i++;
    if (!c->collect ()) continue;
    collected_bytes += c->bytes ();
    collected_clauses++;
    delete_clause (c);
    j--;
  }
  clauses.resize (j - clauses.begin ());
  shrink_vector (clauses);

  VRB ("collect", stats.collections,
    "collected %ld bytes of %ld garbage clauses",
    collected_bytes, collected_clauses);
}

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

// This is the start of the copying garbage collector using the arena.  At
// the core is the following function, which copies a clause to the 'to'
// space of the arena.  Be careful if this clause is a reason of an
// assignment.  In that case update the reason reference.
//
void Internal::copy_clause (Clause * c) {
  LOG (c, "moving");
  assert (!c->moved);
  char * p = c->start (), * q = arena.copy (p, c->bytes ());
  assert (aligned (q, 8));
  Clause * d = c->copy = (Clause *) (q - c->offset ());
  if (d->reason) var (d->literals[val (d->literals[1]) > 0]).reason = d;
  c->moved = true;
}

// This is the moving garbage collector.

void Internal::copy_non_garbage_clauses () {

  Clause * c;

  size_t collected_clauses = 0, collected_bytes = 0;
  size_t     moved_clauses = 0,     moved_bytes = 0;

  // First determine 'moved_bytes' and 'collected_bytes'.
  //
  const const_clause_iterator end = clauses.end ();
  const_clause_iterator i;
  for (i = clauses.begin (); i != end; i++)
    if (!(c = *i)->collect ()) moved_bytes += c->bytes (), moved_clauses++;
    else collected_bytes += c->bytes (), collected_clauses++;

  VRB ("collect", stats.collections,
    "moving %ld bytes %.0f%% of %ld non garbage clauses",
    (long) moved_bytes,
    percent (moved_bytes, collected_bytes + moved_bytes),
    (long) moved_clauses);

  // Prepare 'to' space of size 'moved_bytes'.
  //
  arena.prepare (moved_bytes);

  if (opts.arena == 1 || !watches ()) {

    // Localize according to current clause order.

    // If the option 'opts.arena == 1' is set, then this means the solver
    // uses the original order of clauses.  If there are no watches, we can
    // not use the watched based copying policies below.  This happens if
    // garbage collection is triggered during bounded variable elimination.

    // Copy clauses according to the order of calling 'copy_clause', which
    // in essence just gives a compacting garbage collector, since their
    // relative order is kept, and actually already gives the largest
    // benefit due to better cache locality.

    for (i = clauses.begin (); i != end; i++)
      if (!(c = *i)->collect ()) copy_clause (c);

  } else if (opts.arena == 2) {

    // Localize according to (original) variable order.

    // This is almost the version used by MiniSAT and descendants and seems
    // to work best for search.  Our version uses saved phases.

    for (int sign = -1; sign <= 1; sign += 2) {
      for (int idx = 1; idx <= max_var; idx++) {
        const Watches & ws = watches (sign * phases[idx] * idx);
        const const_watch_iterator ew = ws.end ();
        for (const_watch_iterator i = ws.begin (); i != ew; i++)
          if (!(c = i->clause)->moved && !c->collect ()) copy_clause (c);
      }
    }

  } else {

    // Localize according to decision queue order.

    // This is the default for search. It allocates clauses in the order of
    // the decision queue.  It also uses saved phases.  It seems slightly
    // faster than the MiniSAT version and thus we keep 'opts.arena == 3'.

    assert (opts.arena == 3);

    for (int sign = -1; sign <= 1; sign += 2) {
      for (int idx = queue.last; idx; idx = link (idx).prev) {
        const Watches & ws = watches (sign * phases[idx] * idx);
        const const_watch_iterator ew = ws.end ();
        for (const_watch_iterator i = ws.begin (); i != ew; i++)
          if (!(c = i->clause)->moved && !c->collect ()) copy_clause (c);
      }
    }
  }

  // Do not forget to move clauses which are not watched, which happened in
  // a rare situation, and now is only left as defensive code.
  //
  for (i = clauses.begin (); i != end; i++)
    if (!(c = *i)->collect () && !c->moved) copy_clause (c);

  // Update watches or occurrence lists.
  //
  flush_all_occs_and_watches ();

  // Replace and flush clause references in 'clauses'.
  //
  clause_iterator j = clauses.begin ();
  assert (end == clauses.end ());
  for (i = j; i != end; i++) {
    if ((c = *i)->collect ()) delete_clause (c);
    else assert (c->moved), *j++ = c->copy, deallocate_clause (c);
  }
  clauses.resize (j - clauses.begin ());
  if (clauses.size () < clauses.capacity ()/2) shrink_vector (clauses);

  // Release 'from' space completely and then swap 'to' with 'from'.
  //
  arena.swap ();

  VRB ("collect", stats.collections,
    "collected %ld bytes %.0f%% of %ld garbage clauses",
    (long) collected_bytes,
    percent (collected_bytes, collected_bytes + moved_bytes),
    (long) collected_clauses);
}

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

// Maintaining clause statistics is complex and error prone but necessary
// for proper scheduling of garbage collection, particularly during bounded
// variable elimination.  With this function we can check whether these
// statistics are updated correctly.

void Internal::check_clause_stats () {
#ifndef NDEBUG
  long irredundant = 0, redundant = 0, irrbytes = 0;
  const const_clause_iterator end = clauses.end ();
  const_clause_iterator i;
  for (i = clauses.begin (); i != end; i++) {
    Clause * c = *i;
    if (c->garbage) continue;
    if (c->redundant) redundant++; else irredundant++;
    if (!c->redundant) irrbytes += c->bytes ();
  }
  assert (stats.irredundant == irredundant);
  assert (stats.redundant == redundant);
  assert (stats.irrbytes == irrbytes);
#endif
}

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

bool Internal::arenaing () {
  return opts.arena && (stats.collections > 1);  // TODO more sophisticated
}

void Internal::garbage_collection () {
  if (unsat) return;
  START (collect);
  report ('G', 1);
  stats.collections++;
  mark_satisfied_clauses_as_garbage ();
  if (arenaing ()) copy_non_garbage_clauses ();
  else delete_garbage_clauses ();
  check_clause_stats ();
  check_var_stats ();
  report ('C', 1);
  STOP (collect);
}

};
<|endoftext|>


<commit_before>#include <string>
#include <vector>
#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include <sys/wait.h>
#include <sys/stat.h>

using namespace std;

class command{
	protected:
		vector<string> commandlist;
		bool commandPass;
		bool prevCommandPass;
		string commandType;
		bool allCount;
		bool forceExit;
		string nextConnector;
	public:
		command(){}
		command(vector<string> c){
			commandlist = c;
			commandType = ";";
			allCount = true;
			prevCommandPass = true;
			nextConnector = ";";
			forceExit = false;
		}
		command(vector<string> c, string t){
			commandlist = c;
			commandType = t;
			prevCommandPass = true;
			forceExit = false;
			allCount = true;
			nextConnector = ";";
		}
		bool getPass(){
			return commandPass;
		}
		string getType(){
			return commandType;
		}
		void runCommand(vector<string> com){
			char* argv[1024];

			for(unsigned int i = 0; i < com.size(); i++){
				argv[i] = (char*)com.at(i).c_str();
			}
			argv[com.size()] = NULL;

			pid_t pid;
			int status;
			pid = fork();
			if (pid == 0){
				prevCommandPass = true;
				execvp(argv[0], argv);
				perror("execvp failed: ");
				exit(-1);
			}
			else{
				if (waitpid(pid, &status, 0) == -1){
					perror("Wait: ");
				}
				if (WIFEXITED(status) && WEXITSTATUS(status) != 0){
					prevCommandPass = false;
				}
			}
		}
		void runAllCommands(){
			vector<string> commandsublist;
			unsigned int i = 0;
			unsigned int j = 0;
			while (i < commandlist.size()){
				j = 0;
				if (checkCommandRun()){
					while (!checkBreaker(i)){
						//Exit check
						if (commandlist.at(i) == "exit"){
							cout << "Forced Exit." << endl;
							forceExit = true;
							_Exit(0);
						}
						// Comment check
						if (commandlist.at(i) == "#" || checkComment(commandlist.at(i))){
							runCommand(commandsublist);
							return;
						}
						if (commandlist.at(i) == "["){
							i++;
							cout << "detected";
							commandsublist.push_back(commandlist.at(i));
							if (commandlist.at(i) == "-e" || commandlist.at(i) == "-f" || commandlist.at(i) == "-d"){
								i++;
								commandsublist.push_back(commandlist.at(i));
							}
							else{
								i++;
							}
							if (commandlist.at(i) == "]"){
								i++;
								if (checkTest(commandsublist)){
									cout << "(True)" << endl;
								}
								else{
									cout << "(False)" << endl;
								}
								commandsublist.clear();
							}
							else{
								cout << "Error: Missing close bracket." << endl;
								_exit(1);
							}
							break;
						}
						if (commandlist.at(i) == "test"){
							i++;
							commandsublist.push_back(commandlist.at(i));
							if (commandlist.at(i) == "-e" || commandlist.at(i) == "-f" || commandlist.at(i) == "d"){
								i++;
								commandsublist.push_back(commandlist.at(i));
							}
							else{
								i++;
							}
							if (checkTest(commandsublist)){
								cout << "(True)" << endl;
							}
							else{
								cout << "(False)" << endl;
							}
							commandsublist.clear();
							break;
						}

						//Adds command to the list
						commandsublist.push_back(commandlist.at(i));
						i++;
						j++;
						if (i == commandlist.size()){
							runCommand(commandsublist);
							return;
						}
					}
					if (commandsublist.size() > 0){
						runCommand(commandsublist);
						commandsublist.clear();
					}
					if (checkBreaker(i)){
						if (nextConnector == "||"){
							if (allCount == true){
								prevCommandPass = true;
							}
							else{
								if (prevCommandPass == false){
									allCount = false;
								}
								else{
									allCount = true;
								}
							}
						}
						else if (nextConnector == "&&"){
							if (allCount == true){
								if (prevCommandPass == false){
									allCount = false;
								}
							}
							else{
								allCount = false;
								prevCommandPass = false;
							}
						}
						else if (nextConnector == ";"){
							if (prevCommandPass == true){
								allCount = true;
							}
							else{
								allCount = false;
							}
						}
						if (commandlist.at(i) == "|"){
							nextConnector = "||";
						}
						else if (commandlist.at(i) == "&"){
							nextConnector = "&&";
						}
						else if (commandlist.at(i) == ";"){
							nextConnector = ";";
						}
						i++;
					}
					i++;
				}
				else{
					i++;
				}
			}
		}

		//	Checks if there is a '#' at the front of the string
		bool checkComment(string str){
			if (str.at(0) == '#'){
				return true;
			}
			return false;
		}

		//	Checks if the string is a breaker
		bool checkBreaker(int i){
			if ( (unsigned)i < commandlist.size() + 1){
				if (commandlist.at(i) == "|" && commandlist.at(i + 1) == "|"){
					return true;
				}
				else if (commandlist.at(i) == "&" && commandlist.at(i + 1) == "&"){
					return true;
				}
				else if (commandlist.at(i) == ";"){
					return true;
				}
				else{
					return false;
				}
			}
			else if( (unsigned)i == commandlist.size() + 1){
				if(commandlist.at(i) == ";"){
					return true;
				}
				return false;
			}
			else{
				return false;
			}
		}

		// Checks if the next command should be run
		bool checkCommandRun(){
			if (nextConnector == "||"){
				if(allCount == true){
					return false;
				}
				else{
					return true;
				}
			}
			else if (nextConnector == "&&"){
				if(allCount == true){
					return true;
				}
				return false;
			}
			else if (nextConnector == ";"){
				return true;
			}
			return false;
		}

		bool checkTest(vector<string> temp){
			if (temp.at(0) == "-e"){
				return fileExists(temp.at(1));
			}
			else if (temp.at(0) == "-f"){
				return regFileExists(temp.at(1));
			}
			else if (temp.at(0) == "-d"){
				return dirExists(temp.at(1));
			}
			else{
				return fileExists(temp.at(1));
			}
		}
		bool fileExists(string& path){
			struct stat buffer;
			return (stat(path.c_str(), &buffer) == 0);
		}

		bool dirExists(string& path){
			struct stat buffer;
			if (stat(path.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode)){
				return true;
			}
			return false;
		}

		bool regFileExists(string& path){
			struct stat buffer;
			if (stat(path.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode)){
				return true;
			}
			return false;
		}
		void execute(bool prevCommand){
			if (prevCommand){
				if (commandType == "&&"){
					runAllCommands();
					if (allCount){
						commandPass = true;
					}
					else{
						commandPass = false;
					}
				}
				else if (commandType == "||"){
					commandPass = true;
				}
				else if (commandType == ";"){
					runAllCommands();
					commandPass = true;
				}
			}
			else{
				if (commandType == "&&"){
					commandPass = false;
				}
				else if (commandType == "||"){
					runAllCommands();
					if (allCount){
						commandPass = true;
					}
					else{
						commandPass = false;
					}
				}
				else if (commandType == ";"){
					runAllCommands();
					commandPass = true;
				}
			}
		}

};
<commit_msg>Fixed test functions<commit_after>#include <string>
#include <vector>
#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include <sys/wait.h>
#include <sys/stat.h>

using namespace std;

class command{
	protected:
		vector<string> commandlist;
		bool commandPass;
		bool prevCommandPass;
		string commandType;
		bool allCount;
		bool forceExit;
		string nextConnector;
	public:
		command(){}
		command(vector<string> c){
			commandlist = c;
			commandType = ";";
			allCount = true;
			prevCommandPass = true;
			nextConnector = ";";
			forceExit = false;
		}
		command(vector<string> c, string t){
			commandlist = c;
			commandType = t;
			prevCommandPass = true;
			forceExit = false;
			allCount = true;
			nextConnector = ";";
		}
		bool getPass(){
			return commandPass;
		}
		string getType(){
			return commandType;
		}
		void runCommand(vector<string> com){
			char* argv[1024];

			for(unsigned int i = 0; i < com.size(); i++){
				argv[i] = (char*)com.at(i).c_str();
			}
			argv[com.size()] = NULL;

			pid_t pid;
			int status;
			pid = fork();
			if (pid == 0){
				prevCommandPass = true;
				execvp(argv[0], argv);
				perror("execvp failed: ");
				exit(-1);
			}
			else{
				if (waitpid(pid, &status, 0) == -1){
					perror("Wait: ");
				}
				if (WIFEXITED(status) && WEXITSTATUS(status) != 0){
					prevCommandPass = false;
				}
			}
		}
		void runAllCommands(){
			vector<string> commandsublist;
			unsigned int i = 0;
			unsigned int j = 0;
			while (i < commandlist.size()){
				j = 0;
				if (checkCommandRun()){
					while (!checkBreaker(i)){
						//Exit check
						if (commandlist.at(i) == "exit"){
							cout << "Forced Exit." << endl;
							forceExit = true;
							_Exit(0);
						}
						// Comment check
						if (commandlist.at(i) == "#" || checkComment(commandlist.at(i))){
							runCommand(commandsublist);
							return;
						}
						if (commandlist.at(i) == "["){
							i++;
							commandsublist.push_back(commandlist.at(i));
							if (commandlist.at(i) == "-e" || commandlist.at(i) == "-f" || commandlist.at(i) == "-d"){
								i++;
								commandsublist.push_back(commandlist.at(i));
							}
							i++;
							if (commandlist.at(i) == "]"){
								i++;
								if (checkTest(commandsublist)){
									cout << "(True)" << endl;
								}
								else{
									cout << "(False)" << endl;
								}
								commandsublist.clear();
							}
							else{
								cout << "Error: Missing close bracket." << endl;
								_exit(1);
							}
							break;
						}
						else if (commandlist.at(i) == "test"){
							i++;
							commandsublist.push_back(commandlist.at(i));
							if (commandlist.at(i) == "-e" || commandlist.at(i) == "-f" || commandlist.at(i) == "-d"){
								i++;
								commandsublist.push_back(commandlist.at(i));
							}
							if (checkTest(commandsublist)){
								cout << "(True)" << endl;
							}
							else{
								cout << "(False)" << endl;
							}
							commandsublist.clear();
							break;
						}
						//Adds command to the list
						commandsublist.push_back(commandlist.at(i));
						i++;
						j++;
						if (i == commandlist.size()){
							runCommand(commandsublist);
							return;
						}
					}
					if (commandsublist.size() > 0){
						runCommand(commandsublist);
						commandsublist.clear();
					}
					if (i >= commandlist.size()){
						return;
					}
					if (checkBreaker(i)){
						if (nextConnector == "||"){
							if (allCount == true){
								prevCommandPass = true;
							}
							else{
								if (prevCommandPass == false){
									allCount = false;
								}
								else{
									allCount = true;
								}
							}
						}
						else if (nextConnector == "&&"){
							if (allCount == true){
								if (prevCommandPass == false){
									allCount = false;
								}
							}
							else{
								allCount = false;
								prevCommandPass = false;
							}
						}
						else if (nextConnector == ";"){
							if (prevCommandPass == true){
								allCount = true;
							}
							else{
								allCount = false;
							}
						}
						if (commandlist.at(i) == "|"){
							nextConnector = "||";
						}
						else if (commandlist.at(i) == "&"){
							nextConnector = "&&";
						}
						else if (commandlist.at(i) == ";"){
							nextConnector = ";";
						}
						i++;
					}
					i++;
				}
				else{
					i++;
				}
			}
		}

		//	Checks if there is a '#' at the front of the string
		bool checkComment(string str){
			if (str.at(0) == '#'){
				return true;
			}
			return false;
		}

		//	Checks if the string is a breaker
		bool checkBreaker(int i){
			if ( (unsigned)i < commandlist.size() + 1){
				if (commandlist.at(i) == "|" && commandlist.at(i + 1) == "|"){
					return true;
				}
				else if (commandlist.at(i) == "&" && commandlist.at(i + 1) == "&"){
					return true;
				}
				else if (commandlist.at(i) == ";"){
					return true;
				}
				else{
					return false;
				}
			}
			else if( (unsigned)i == commandlist.size() + 1){
				if(commandlist.at(i) == ";"){
					return true;
				}
				return false;
			}
			else{
				return false;
			}
		}

		// Checks if the next command should be run
		bool checkCommandRun(){
			if (nextConnector == "||"){
				if(allCount == true){
					return false;
				}
				else{
					return true;
				}
			}
			else if (nextConnector == "&&"){
				if(allCount == true){
					return true;
				}
				return false;
			}
			else if (nextConnector == ";"){
				return true;
			}
			return false;
		}

		bool checkTest(vector<string> temp){
			if (temp.at(0) == "-e"){
				return fileExists(temp.at(1));
			}
			else if (temp.at(0) == "-f"){
				return regFileExists(temp.at(1));
			}
			else if (temp.at(0) == "-d"){
				return dirExists(temp.at(1));
			}
			else{
				return fileExists(temp.at(0));
			}
		}
		bool fileExists(string& path){
			struct stat buffer;
			return (stat(path.c_str(), &buffer) == 0);
		}

		bool dirExists(string& path){
			struct stat buffer;
			if (stat(path.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode)){
				return true;
			}
			return false;
		}

		bool regFileExists(string& path){
			struct stat buffer;
			if (stat(path.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode)){
				return true;
			}
			return false;
		}
		void execute(bool prevCommand){
			if (prevCommand){
				if (commandType == "&&"){
					runAllCommands();
					if (allCount){
						commandPass = true;
					}
					else{
						commandPass = false;
					}
				}
				else if (commandType == "||"){
					commandPass = true;
				}
				else if (commandType == ";"){
					runAllCommands();
					commandPass = true;
				}
			}
			else{
				if (commandType == "&&"){
					commandPass = false;
				}
				else if (commandType == "||"){
					runAllCommands();
					if (allCount){
						commandPass = true;
					}
					else{
						commandPass = false;
					}
				}
				else if (commandType == ";"){
					runAllCommands();
					commandPass = true;
				}
			}
		}

};
<|endoftext|>


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

//id of the existing window menu item
#define WINDOW_MENUITEMTAG 4999
#if defined(OS_WIN)
const ExtensionString WINDOW_COMMAND    = L"window";
#else
const ExtensionString WINDOW_COMMAND    = "window";
#endif

// map of menuParent --> NativeMenuModel instance
typedef std::map<void*, NativeMenuModel*> menuModelMap;
menuModelMap instanceMap;

NativeMenuModel& NativeMenuModel::getInstance(void* menuParent, bool reset)
{
    menuModelMap::iterator foundItem = instanceMap.find(menuParent);

    if (foundItem != instanceMap.end()) {
        return *(foundItem->second);
    }

    menu m;
    NativeMenuModel* instance = new NativeMenuModel(m);
    instance->setTag(WINDOW_COMMAND, WINDOW_MENUITEMTAG);
    instanceMap[menuParent] = instance;
    return *(instance);
}

bool NativeMenuModel::isMenuItemEnabled(int tag) {
    menu::iterator foundItem = menuItems.find(tag);
    if(foundItem == menuItems.end()) {
        //return enabled
        return true;
    }
    return foundItem->second.enabled;
}

bool NativeMenuModel::isMenuItemChecked(int tag) {
    menu::iterator foundItem = menuItems.find(tag);
    if(foundItem == menuItems.end()) {
        return false;
    }
    return foundItem->second.checked;
}

int NativeMenuModel::setMenuItemState (ExtensionString command, bool enabled, bool checked) {
    //woo turning O(log n) into O(n) however, the important look up is the tag -> menu so making sure that is faster as it will impact user performance.
    menu::iterator it;
    for ( it=menuItems.begin() ; it != menuItems.end(); it++ ) {
        if(it->second.commandId.compare(command) == 0) {
            it->second.enabled = enabled;
            it->second.checked = checked;
            return NO_ERROR;
        }
    }
    return ERR_NOT_FOUND;
}

ExtensionString NativeMenuModel::getCommandId(int tag) {
    return menuItems[tag].commandId;
}

int NativeMenuModel::getOrCreateTag(ExtensionString command)
{
    menuTag::iterator foundItem = commandMap.find(command);
    if(foundItem == commandMap.end()) {
        commandMap[command] = ++tagCount;
        menuItems[tagCount] = NativeMenuItemModel(command, true, false);
        return tagCount;
    }
    return foundItem->second;
}

int NativeMenuModel::setTag(ExtensionString command, int tag)
{
    menuTag::iterator foundItem = commandMap.find(command);
    if(foundItem == commandMap.end()) {
        commandMap[command] = tag;
        menuItems[tag] = NativeMenuItemModel(command, true, false);
        return tagCount;
    }
    return foundItem->second;
}

int NativeMenuModel::getTag(ExtensionString command)
{
    menuTag::iterator foundItem = commandMap.find(command);
    if(foundItem == commandMap.end()) {
        return -1;
    }
    return foundItem->second;
}

void NativeMenuModel::setOsItem (int tag, void* theItem) {
    menuItems[tag].osItem = theItem;
}

void* NativeMenuModel::getOsItem (int tag) {
	 return menuItems[tag].osItem;
}

int NativeMenuModel::removeMenuItem(const ExtensionString& command)
{
    menuTag::iterator foundItem = commandMap.find(command);
    if(foundItem == commandMap.end()) {
        return ERR_NOT_FOUND;
    }
    menuItems.erase(foundItem->second);
    commandMap.erase(foundItem);
    return NO_ERROR;
}
<commit_msg>More review comments.<commit_after>/*
 * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
#include "native_menu_model.h"
#include "command_callbacks.h"

//id of the existing window menu item
#define WINDOW_MENUITEMTAG 4999
#if defined(OS_WIN)
const ExtensionString WINDOW_COMMAND    = L"window";
#else
const ExtensionString WINDOW_COMMAND    = "window";
#endif

// map of menuParent --> NativeMenuModel instance
typedef std::map<void*, NativeMenuModel*> menuModelMap;
menuModelMap instanceMap;

NativeMenuModel& NativeMenuModel::getInstance(void* menuParent, bool reset)
{
    menuModelMap::iterator foundItem = instanceMap.find(menuParent);

    if (foundItem != instanceMap.end()) {
        return *(foundItem->second);
    }

    menu m;
    NativeMenuModel* instance = new NativeMenuModel(m);
    instance->setTag(WINDOW_COMMAND, WINDOW_MENUITEMTAG);
    instanceMap[menuParent] = instance;
    return *(instance);
}

bool NativeMenuModel::isMenuItemEnabled(int tag) {
    menu::iterator foundItem = menuItems.find(tag);
    if(foundItem == menuItems.end()) {
        //return enabled
        return true;
    }
    return foundItem->second.enabled;
}

bool NativeMenuModel::isMenuItemChecked(int tag) {
    menu::iterator foundItem = menuItems.find(tag);
    if(foundItem == menuItems.end()) {
        return false;
    }
    return foundItem->second.checked;
}

int NativeMenuModel::setMenuItemState (ExtensionString command, bool enabled, bool checked) {
    //woo turning O(log n) into O(n) however, the important look up is the tag -> menu so making sure that is faster as it will impact user performance.
    menu::iterator it;
    for ( it=menuItems.begin() ; it != menuItems.end(); it++ ) {
        if(it->second.commandId.compare(command) == 0) {
            it->second.enabled = enabled;
            it->second.checked = checked;
            return NO_ERROR;
        }
    }
    return ERR_NOT_FOUND;
}

ExtensionString NativeMenuModel::getCommandId(int tag) {
    menu::iterator foundItem = menuItems.find(tag);
    if(foundItem == menuItems.end()) {
        return "";
    }
    return menuItems[tag].commandId;
}

int NativeMenuModel::getOrCreateTag(ExtensionString command)
{
    menuTag::iterator foundItem = commandMap.find(command);
    if(foundItem == commandMap.end()) {
        commandMap[command] = ++tagCount;
        menuItems[tagCount] = NativeMenuItemModel(command, true, false);
        return tagCount;
    }
    return foundItem->second;
}

int NativeMenuModel::setTag(ExtensionString command, int tag)
{
    menuTag::iterator foundItem = commandMap.find(command);
    if(foundItem == commandMap.end()) {
        commandMap[command] = tag;
        menuItems[tag] = NativeMenuItemModel(command, true, false);
        return tagCount;
    }
    return foundItem->second;
}

int NativeMenuModel::getTag(ExtensionString command)
{
    menuTag::iterator foundItem = commandMap.find(command);
    if(foundItem == commandMap.end()) {
        return -1;
    }
    return foundItem->second;
}

void NativeMenuModel::setOsItem (int tag, void* theItem) {
    menu::iterator foundItem = menuItems.find(tag);
    if(foundItem == menuItems.end()) {
        return;
    }
    menuItems[tag].osItem = theItem;
}

void* NativeMenuModel::getOsItem (int tag) {
    menu::iterator foundItem = menuItems.find(tag);
    if(foundItem == menuItems.end()) {
        return NULL;
    }
	 return menuItems[tag].osItem;
}

int NativeMenuModel::removeMenuItem(const ExtensionString& command)
{
    menuTag::iterator foundItem = commandMap.find(command);
    if(foundItem == commandMap.end()) {
        return ERR_NOT_FOUND;
    }
    menuItems.erase(foundItem->second);
    commandMap.erase(foundItem);
    return NO_ERROR;
}
<|endoftext|>