<commit_before>/*-------------------------------------------------------------------------
 *
 *   FILE
 *	pqxx/transaction_base.hxx
 *
 *   DESCRIPTION
 *      common code and definitions for the transaction classes.
 *   pqxx::transaction_base defines the interface for any abstract class that
 *   represents a database transaction
 *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead.
 *
 * Copyright (c) 2001-2007, Jeroen T. Vermeulen <jtv@xs4all.nl>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 *
 *-------------------------------------------------------------------------
 */
#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"

/* End-user programs need not include this file, unless they define their own
 * transaction classes.  This is not something the typical program should want
 * to do.
 *
 * However, reading this file is worthwhile because it defines the public
 * interface for the available transaction classes such as transaction and
 * nontransaction.
 */

#include "pqxx/connection_base"
#include "pqxx/isolation"
#include "pqxx/result"

/* Methods tested in eg. self-test program test001 are marked with "//[t1]"
 */

namespace pqxx
{
class connection_base;
class transaction_base;

namespace internal
{
class lowlevel_cursor;

class PQXX_LIBEXPORT transactionfocus : public virtual namedclass
{
public:
  explicit transactionfocus(transaction_base &t) :
    namedclass("transactionfocus"),
    m_Trans(t),
    m_registered(false)
  {
  }

protected:
  void register_me();
  void unregister_me() throw ();
  void reg_pending_error(const PGSTD::string &) throw ();
  bool registered() const throw () { return m_registered; }

  transaction_base &m_Trans;

private:
  bool m_registered;

  /// Not allowed
  transactionfocus();
  /// Not allowed
  transactionfocus(const transactionfocus &);
  /// Not allowed
  transactionfocus &operator=(const transactionfocus &);
};

} // namespace internal

/// Interface definition (and common code) for "transaction" classes.
/**
 * @addtogroup transaction Transaction classes
 * All database access must be channeled through one of these classes for
 * safety, although not all implementations of this interface need to provide
 * full transactional integrity.
 *
 * Several implementations of this interface are shipped with libpqxx, including
 * the plain transaction class, the entirely unprotected nontransaction, and the
 * more cautions robusttransaction.
 */
class PQXX_LIBEXPORT transaction_base : public virtual internal::namedclass
{
public:
  /// If nothing else is known, our isolation level is at least read_committed
  typedef isolation_traits<read_committed> isolation_tag;

  virtual ~transaction_base() =0;					//[t1]

  /// Commit the transaction
  /** Unless this function is called explicitly, the transaction will not be
   * committed (actually the nontransaction implementation breaks this rule,
   * hence the name).
   *
   * Once this function returns, the whole transaction will typically be
   * irrevocably completed in the database.  There is also, however, a minute
   * risk that the connection to the database may be lost at just the wrong
   * moment.  In that case, libpqxx may be unable to determine whether the
   * transaction was completed or aborted and an in_doubt_error will be thrown
   * to make this fact known to the caller.  The robusttransaction
   * implementation takes some special precautions to reduce this risk.
   */
  void commit();							//[t1]

  /// Abort the transaction
  /** No special effort is required to call this function; it will be called
   * implicitly when the transaction is destructed.
   */
  void abort();								//[t10]

  /**
   * @addtogroup escaping String escaping
   */
  //@{
  /// Escape string for use as SQL string literal in this transaction
  PGSTD::string esc(const char str[]) const;				//[t90]
  /// Escape string for use as SQL string literal in this transaction
  PGSTD::string esc(const char str[], size_t maxlen) const		//[t90]
	{ return m_Conn.esc(str,maxlen); }
  /// Escape string for use as SQL string literal in this transaction
  PGSTD::string esc(const PGSTD::string &) const;			//[t90]

  /// Escape binary data for use as SQL string literal in this transaction
  /** Raw, binary data is treated differently from regular strings.  Binary
   * strings are never interpreted as text, so they may safely include byte
   * values or byte sequences that don't happen to represent valid characters in
   * the character encoding being used.
   *
   * The binary string does not stop at the first zero byte, as is the case with
   * textual strings.  Instead, they may contain zero bytes anywhere.  If it
   * happens to contain bytes that look like quote characters, or other things
   * that can disrupt their use in SQL queries, they will be replaced with
   * special escape sequences.
   */
  PGSTD::string esc_raw(const unsigned char str[], size_t len) const	//[t62]
	{ return m_Conn.esc_raw(str, len); }
  /// Escape binary data for use as SQL string literal in this transaction
  PGSTD::string esc_raw(const PGSTD::string &) const;			//[t62]
  //@}

  /// Execute query
  /** Perform a query in this transaction.
   *
   * This is one of the most important functions in libpqxx.
   *
   * Most libpqxx exceptions can be thrown from here, including sql_error,
   * broken_connection, and many sql_error subtypes such as
   * feature_not_supported or insufficient_privilege.  But any exception thrown
   * by the C++ standard library may also occur here.  All exceptions will be
   * derived from std::exception, however, and all libpqxx-specific exception
   * types are derived from pqxx::pqxx_exception.
   *
   * @param Query Query or command to execute
   * @param Desc Optional identifier for query, to help pinpoint SQL errors
   * @return A result set describing the query's or command's result
   */
  result exec(const PGSTD::string &Query,
	      const PGSTD::string &Desc=PGSTD::string());		//[t1]

  result exec(const PGSTD::stringstream &Query,
	      const PGSTD::string &Desc=PGSTD::string())		//[t9]
	{ return exec(Query.str(), Desc); }

  /**
   * @name Prepared statements
   */
  //@{
  /// Execute prepared statement
  /** Prepared statements are defined using the connection classes' prepare()
   * function, and continue to live on in the ongoing session regardless of
   * the context they were defined in (unless explicitly dropped using the
   * connection's unprepare() function).  Their execution however, like other
   * forms of query execution, requires a transaction object.
   *
   * Just like param_declaration is a helper class that lets you tag parameter
   * declarations onto the statement declaration, the invocation class returned
   * here lets you tag parameter values onto the call:
   *
   * @code
   * result run_mystatement(transaction_base &T)
   * {
   *   return T.prepared("mystatement")("param1")(2)()(4).exec();
   * }
   * @endcode
   *
   * Here, parameter 1 (written as "<tt>$1</tt>" in the statement's body) is a
   * string that receives the value "param1"; the second parameter is an integer
   * with the value 2; the third receives a null, making its type irrelevant;
   * and number 4 again is an integer.  The ultimate invocation of exec() is
   * essential; if you forget this, nothing happens.
   *
   * @warning Do not try to execute a prepared statement manually through direct
   * SQL statements.  This is likely not to work, and even if it does, is likely
   * to be slower than using the proper libpqxx functions.  Also, libpqxx knows
   * how to emulate prepared statements if some part of the infrastructure does
   * not support them.
   *
   * @warning Actual definition of the prepared statement on the backend may be
   * deferred until its first use, which means that any errors in the prepared
   * statement may not show up until it is executed--and perhaps abort the
   * ongoing transaction in the process.
   */
  prepare::invocation prepared(const PGSTD::string &statement);		//[t85]

  //@}

  /**
   * @name Error/warning output
   */
  //@{
  /// Have connection process warning message
  void process_notice(const char Msg[]) const				//[t14]
	{ m_Conn.process_notice(Msg); }
  /// Have connection process warning message
  void process_notice(const PGSTD::string &Msg) const			//[t14]
	{ m_Conn.process_notice(Msg); }
  //@}

  /// Connection this transaction is running in
  connection_base &conn() const { return m_Conn; }			//[t4]

  /// Set session variable in this connection
  /** The new value is typically forgotten if the transaction aborts.
   * Known exceptions to this rule are nontransaction, and PostgreSQL versions
   * prior to 7.3.  In the case of nontransaction, the set value will be kept
   * regardless; but in that case, if the connection ever needs to be recovered,
   * the set value will not be restored.
   * @param Var The variable to set
   * @param Val The new value to store in the variable
   */
  void set_variable(const PGSTD::string &Var, const PGSTD::string &Val);//[t61]

  /// Get currently applicable value of variable
  /** First consults an internal cache of variables that have been set (whether
   * in the ongoing transaction or in the connection) using the set_variable
   * functions.  If it is not found there, the database is queried.
   *
   * @warning Do not mix the set_variable with raw "SET" queries, and do not
   * try to set or get variables while a pipeline or table stream is active.
   *
   * @warning This function used to be declared as @c const but isn't anymore.
   */
  PGSTD::string get_variable(const PGSTD::string &);			//[t61]

protected:
  /// Create a transaction (to be called by implementation classes only)
  /** The optional name, if nonempty, must begin with a letter and may contain
   * letters and digits only.
   *
   * @param direct running directly in connection context (i.e. not nested)?
   */
  explicit transaction_base(connection_base &, bool direct=true);

  /// Begin transaction (to be called by implementing class)
  /** Will typically be called from implementing class' constructor.
   */
  void Begin();

  /// End transaction.  To be called by implementing class' destructor
  void End() throw ();

  /// To be implemented by derived implementation class: start transaction
  virtual void do_begin() =0;
  /// To be implemented by derived implementation class: perform query
  virtual result do_exec(const char Query[]) =0;
  /// To be implemented by derived implementation class: commit transaction
  virtual void do_commit() =0;
  /// To be implemented by derived implementation class: abort transaction
  virtual void do_abort() =0;

  // For use by implementing class:

  /// Execute query on connection directly
  /**
   * @param C Query or command to execute
   * @param Retries Number of times to retry the query if it fails.  Be
   * extremely careful with this option; if you retry in the middle of a
   * transaction, you may be setting up a new connection transparently and
   * executing the latter part of the transaction without a backend transaction
   * being active (and with the former part aborted).
   */
  result DirectExec(const char C[], int Retries=0);

  /// Forget about any reactivation-blocking resources we tried to allocate
  void reactivation_avoidance_clear() throw ()
	{m_reactivation_avoidance.clear();}

private:
  /* A transaction goes through the following stages in its lifecycle:
   * <ul>
   * <li> nascent: the transaction hasn't actually begun yet.  If our connection
   *    fails at this stage, it may recover and the transaction can attempt to
   *    establish itself again.
   * <li> active: the transaction has begun.  Since no commit command has been
   *    issued, abortion is implicit if the connection fails now.
   * <li> aborted: an abort has been issued; the transaction is terminated and
   *    its changes to the database rolled back.  It will accept no further
   *    commands.
   * <li> committed: the transaction has completed successfully, meaning that a
   *    commit has been issued.  No further commands are accepted.
   * <li> in_doubt: the connection was lost at the exact wrong time, and there
   *    is no way of telling whether the transaction was committed or aborted.
   * </ul>
   *
   * Checking and maintaining state machine logic is the responsibility of the
   * base class (ie., this one).
   */
  enum Status
  {
    st_nascent,
    st_active,
    st_aborted,
    st_committed,
    st_in_doubt
  };

  void PQXX_PRIVATE CheckPendingError();

  template<typename T> bool parm_is_null(T *p) const throw () { return !p; }
  template<typename T> bool parm_is_null(T) const throw () { return false; }

  friend class Cursor;
  friend class pqxx::internal::lowlevel_cursor;
  void MakeEmpty(result &R) const { m_Conn.MakeEmpty(R); }

  friend class internal::transactionfocus;
  void PQXX_PRIVATE RegisterFocus(internal::transactionfocus *);
  void PQXX_PRIVATE UnregisterFocus(internal::transactionfocus *) throw ();
  void PQXX_PRIVATE RegisterPendingError(const PGSTD::string &) throw ();
  friend class tablereader;
  void PQXX_PRIVATE BeginCopyRead(const PGSTD::string &, const PGSTD::string &);
  bool ReadCopyLine(PGSTD::string &L) { return m_Conn.ReadCopyLine(L); }
  friend class tablewriter;
  void PQXX_PRIVATE BeginCopyWrite(const PGSTD::string &Table,
	const PGSTD::string &Columns = PGSTD::string());
  void WriteCopyLine(const PGSTD::string &L) { m_Conn.WriteCopyLine(L); }
  void EndCopyWrite() { m_Conn.EndCopyWrite(); }

  friend class pipeline;
  void start_exec(const PGSTD::string &Q) { m_Conn.start_exec(Q); }
  internal::pq::PGresult *get_result() { return m_Conn.get_result(); }
  void consume_input() throw () { m_Conn.consume_input(); }
  bool is_busy() const throw () { return m_Conn.is_busy(); }

  friend class prepare::invocation;
  result prepared_exec(const PGSTD::string &,
	const char *const[],
	const int[],
	int);

  connection_base &m_Conn;

  internal::unique<internal::transactionfocus> m_Focus;
  Status m_Status;
  bool m_Registered;
  PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
  PGSTD::string m_PendingError;

  friend class subtransaction;
  /// Resources allocated in this transaction that make reactivation impossible
  /** This number may be negative!
   */
  internal::reactivation_avoidance_counter m_reactivation_avoidance;

  /// Not allowed
  transaction_base();
  /// Not allowed
  transaction_base(const transaction_base &);
  /// Not allowed
  transaction_base &operator=(const transaction_base &);
};

} // namespace pqxx

#include "pqxx/compiler-internal-post.hxx"
<commit_msg>Let cursor_base access m_reactivation_avoidance.  Thanks Richard B. Kreckel.<commit_after>/*-------------------------------------------------------------------------
 *
 *   FILE
 *	pqxx/transaction_base.hxx
 *
 *   DESCRIPTION
 *      common code and definitions for the transaction classes.
 *   pqxx::transaction_base defines the interface for any abstract class that
 *   represents a database transaction
 *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead.
 *
 * Copyright (c) 2001-2007, Jeroen T. Vermeulen <jtv@xs4all.nl>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 *
 *-------------------------------------------------------------------------
 */
#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"

/* End-user programs need not include this file, unless they define their own
 * transaction classes.  This is not something the typical program should want
 * to do.
 *
 * However, reading this file is worthwhile because it defines the public
 * interface for the available transaction classes such as transaction and
 * nontransaction.
 */

#include "pqxx/connection_base"
#include "pqxx/isolation"
#include "pqxx/result"

/* Methods tested in eg. self-test program test001 are marked with "//[t1]"
 */

namespace pqxx
{
class connection_base;
class transaction_base;

namespace internal
{
class lowlevel_cursor;

class PQXX_LIBEXPORT transactionfocus : public virtual namedclass
{
public:
  explicit transactionfocus(transaction_base &t) :
    namedclass("transactionfocus"),
    m_Trans(t),
    m_registered(false)
  {
  }

protected:
  void register_me();
  void unregister_me() throw ();
  void reg_pending_error(const PGSTD::string &) throw ();
  bool registered() const throw () { return m_registered; }

  transaction_base &m_Trans;

private:
  bool m_registered;

  /// Not allowed
  transactionfocus();
  /// Not allowed
  transactionfocus(const transactionfocus &);
  /// Not allowed
  transactionfocus &operator=(const transactionfocus &);
};

} // namespace internal

/// Interface definition (and common code) for "transaction" classes.
/**
 * @addtogroup transaction Transaction classes
 * All database access must be channeled through one of these classes for
 * safety, although not all implementations of this interface need to provide
 * full transactional integrity.
 *
 * Several implementations of this interface are shipped with libpqxx, including
 * the plain transaction class, the entirely unprotected nontransaction, and the
 * more cautions robusttransaction.
 */
class PQXX_LIBEXPORT transaction_base : public virtual internal::namedclass
{
public:
  /// If nothing else is known, our isolation level is at least read_committed
  typedef isolation_traits<read_committed> isolation_tag;

  virtual ~transaction_base() =0;					//[t1]

  /// Commit the transaction
  /** Unless this function is called explicitly, the transaction will not be
   * committed (actually the nontransaction implementation breaks this rule,
   * hence the name).
   *
   * Once this function returns, the whole transaction will typically be
   * irrevocably completed in the database.  There is also, however, a minute
   * risk that the connection to the database may be lost at just the wrong
   * moment.  In that case, libpqxx may be unable to determine whether the
   * transaction was completed or aborted and an in_doubt_error will be thrown
   * to make this fact known to the caller.  The robusttransaction
   * implementation takes some special precautions to reduce this risk.
   */
  void commit();							//[t1]

  /// Abort the transaction
  /** No special effort is required to call this function; it will be called
   * implicitly when the transaction is destructed.
   */
  void abort();								//[t10]

  /**
   * @addtogroup escaping String escaping
   */
  //@{
  /// Escape string for use as SQL string literal in this transaction
  PGSTD::string esc(const char str[]) const;				//[t90]
  /// Escape string for use as SQL string literal in this transaction
  PGSTD::string esc(const char str[], size_t maxlen) const		//[t90]
	{ return m_Conn.esc(str,maxlen); }
  /// Escape string for use as SQL string literal in this transaction
  PGSTD::string esc(const PGSTD::string &) const;			//[t90]

  /// Escape binary data for use as SQL string literal in this transaction
  /** Raw, binary data is treated differently from regular strings.  Binary
   * strings are never interpreted as text, so they may safely include byte
   * values or byte sequences that don't happen to represent valid characters in
   * the character encoding being used.
   *
   * The binary string does not stop at the first zero byte, as is the case with
   * textual strings.  Instead, they may contain zero bytes anywhere.  If it
   * happens to contain bytes that look like quote characters, or other things
   * that can disrupt their use in SQL queries, they will be replaced with
   * special escape sequences.
   */
  PGSTD::string esc_raw(const unsigned char str[], size_t len) const	//[t62]
	{ return m_Conn.esc_raw(str, len); }
  /// Escape binary data for use as SQL string literal in this transaction
  PGSTD::string esc_raw(const PGSTD::string &) const;			//[t62]
  //@}

  /// Execute query
  /** Perform a query in this transaction.
   *
   * This is one of the most important functions in libpqxx.
   *
   * Most libpqxx exceptions can be thrown from here, including sql_error,
   * broken_connection, and many sql_error subtypes such as
   * feature_not_supported or insufficient_privilege.  But any exception thrown
   * by the C++ standard library may also occur here.  All exceptions will be
   * derived from std::exception, however, and all libpqxx-specific exception
   * types are derived from pqxx::pqxx_exception.
   *
   * @param Query Query or command to execute
   * @param Desc Optional identifier for query, to help pinpoint SQL errors
   * @return A result set describing the query's or command's result
   */
  result exec(const PGSTD::string &Query,
	      const PGSTD::string &Desc=PGSTD::string());		//[t1]

  result exec(const PGSTD::stringstream &Query,
	      const PGSTD::string &Desc=PGSTD::string())		//[t9]
	{ return exec(Query.str(), Desc); }

  /**
   * @name Prepared statements
   */
  //@{
  /// Execute prepared statement
  /** Prepared statements are defined using the connection classes' prepare()
   * function, and continue to live on in the ongoing session regardless of
   * the context they were defined in (unless explicitly dropped using the
   * connection's unprepare() function).  Their execution however, like other
   * forms of query execution, requires a transaction object.
   *
   * Just like param_declaration is a helper class that lets you tag parameter
   * declarations onto the statement declaration, the invocation class returned
   * here lets you tag parameter values onto the call:
   *
   * @code
   * result run_mystatement(transaction_base &T)
   * {
   *   return T.prepared("mystatement")("param1")(2)()(4).exec();
   * }
   * @endcode
   *
   * Here, parameter 1 (written as "<tt>$1</tt>" in the statement's body) is a
   * string that receives the value "param1"; the second parameter is an integer
   * with the value 2; the third receives a null, making its type irrelevant;
   * and number 4 again is an integer.  The ultimate invocation of exec() is
   * essential; if you forget this, nothing happens.
   *
   * @warning Do not try to execute a prepared statement manually through direct
   * SQL statements.  This is likely not to work, and even if it does, is likely
   * to be slower than using the proper libpqxx functions.  Also, libpqxx knows
   * how to emulate prepared statements if some part of the infrastructure does
   * not support them.
   *
   * @warning Actual definition of the prepared statement on the backend may be
   * deferred until its first use, which means that any errors in the prepared
   * statement may not show up until it is executed--and perhaps abort the
   * ongoing transaction in the process.
   */
  prepare::invocation prepared(const PGSTD::string &statement);		//[t85]

  //@}

  /**
   * @name Error/warning output
   */
  //@{
  /// Have connection process warning message
  void process_notice(const char Msg[]) const				//[t14]
	{ m_Conn.process_notice(Msg); }
  /// Have connection process warning message
  void process_notice(const PGSTD::string &Msg) const			//[t14]
	{ m_Conn.process_notice(Msg); }
  //@}

  /// Connection this transaction is running in
  connection_base &conn() const { return m_Conn; }			//[t4]

  /// Set session variable in this connection
  /** The new value is typically forgotten if the transaction aborts.
   * Known exceptions to this rule are nontransaction, and PostgreSQL versions
   * prior to 7.3.  In the case of nontransaction, the set value will be kept
   * regardless; but in that case, if the connection ever needs to be recovered,
   * the set value will not be restored.
   * @param Var The variable to set
   * @param Val The new value to store in the variable
   */
  void set_variable(const PGSTD::string &Var, const PGSTD::string &Val);//[t61]

  /// Get currently applicable value of variable
  /** First consults an internal cache of variables that have been set (whether
   * in the ongoing transaction or in the connection) using the set_variable
   * functions.  If it is not found there, the database is queried.
   *
   * @warning Do not mix the set_variable with raw "SET" queries, and do not
   * try to set or get variables while a pipeline or table stream is active.
   *
   * @warning This function used to be declared as @c const but isn't anymore.
   */
  PGSTD::string get_variable(const PGSTD::string &);			//[t61]

protected:
  /// Create a transaction (to be called by implementation classes only)
  /** The optional name, if nonempty, must begin with a letter and may contain
   * letters and digits only.
   *
   * @param direct running directly in connection context (i.e. not nested)?
   */
  explicit transaction_base(connection_base &, bool direct=true);

  /// Begin transaction (to be called by implementing class)
  /** Will typically be called from implementing class' constructor.
   */
  void Begin();

  /// End transaction.  To be called by implementing class' destructor
  void End() throw ();

  /// To be implemented by derived implementation class: start transaction
  virtual void do_begin() =0;
  /// To be implemented by derived implementation class: perform query
  virtual result do_exec(const char Query[]) =0;
  /// To be implemented by derived implementation class: commit transaction
  virtual void do_commit() =0;
  /// To be implemented by derived implementation class: abort transaction
  virtual void do_abort() =0;

  // For use by implementing class:

  /// Execute query on connection directly
  /**
   * @param C Query or command to execute
   * @param Retries Number of times to retry the query if it fails.  Be
   * extremely careful with this option; if you retry in the middle of a
   * transaction, you may be setting up a new connection transparently and
   * executing the latter part of the transaction without a backend transaction
   * being active (and with the former part aborted).
   */
  result DirectExec(const char C[], int Retries=0);

  /// Forget about any reactivation-blocking resources we tried to allocate
  void reactivation_avoidance_clear() throw ()
	{m_reactivation_avoidance.clear();}

private:
  /* A transaction goes through the following stages in its lifecycle:
   * <ul>
   * <li> nascent: the transaction hasn't actually begun yet.  If our connection
   *    fails at this stage, it may recover and the transaction can attempt to
   *    establish itself again.
   * <li> active: the transaction has begun.  Since no commit command has been
   *    issued, abortion is implicit if the connection fails now.
   * <li> aborted: an abort has been issued; the transaction is terminated and
   *    its changes to the database rolled back.  It will accept no further
   *    commands.
   * <li> committed: the transaction has completed successfully, meaning that a
   *    commit has been issued.  No further commands are accepted.
   * <li> in_doubt: the connection was lost at the exact wrong time, and there
   *    is no way of telling whether the transaction was committed or aborted.
   * </ul>
   *
   * Checking and maintaining state machine logic is the responsibility of the
   * base class (ie., this one).
   */
  enum Status
  {
    st_nascent,
    st_active,
    st_aborted,
    st_committed,
    st_in_doubt
  };

  void PQXX_PRIVATE CheckPendingError();

  template<typename T> bool parm_is_null(T *p) const throw () { return !p; }
  template<typename T> bool parm_is_null(T) const throw () { return false; }

  friend class Cursor;
  friend class cursor_base;
  friend class pqxx::internal::lowlevel_cursor;
  void MakeEmpty(result &R) const { m_Conn.MakeEmpty(R); }

  friend class internal::transactionfocus;
  void PQXX_PRIVATE RegisterFocus(internal::transactionfocus *);
  void PQXX_PRIVATE UnregisterFocus(internal::transactionfocus *) throw ();
  void PQXX_PRIVATE RegisterPendingError(const PGSTD::string &) throw ();
  friend class tablereader;
  void PQXX_PRIVATE BeginCopyRead(const PGSTD::string &, const PGSTD::string &);
  bool ReadCopyLine(PGSTD::string &L) { return m_Conn.ReadCopyLine(L); }
  friend class tablewriter;
  void PQXX_PRIVATE BeginCopyWrite(const PGSTD::string &Table,
	const PGSTD::string &Columns = PGSTD::string());
  void WriteCopyLine(const PGSTD::string &L) { m_Conn.WriteCopyLine(L); }
  void EndCopyWrite() { m_Conn.EndCopyWrite(); }

  friend class pipeline;
  void start_exec(const PGSTD::string &Q) { m_Conn.start_exec(Q); }
  internal::pq::PGresult *get_result() { return m_Conn.get_result(); }
  void consume_input() throw () { m_Conn.consume_input(); }
  bool is_busy() const throw () { return m_Conn.is_busy(); }

  friend class prepare::invocation;
  result prepared_exec(const PGSTD::string &,
	const char *const[],
	const int[],
	int);

  connection_base &m_Conn;

  internal::unique<internal::transactionfocus> m_Focus;
  Status m_Status;
  bool m_Registered;
  PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
  PGSTD::string m_PendingError;

  friend class subtransaction;
  /// Resources allocated in this transaction that make reactivation impossible
  /** This number may be negative!
   */
  internal::reactivation_avoidance_counter m_reactivation_avoidance;

  /// Not allowed
  transaction_base();
  /// Not allowed
  transaction_base(const transaction_base &);
  /// Not allowed
  transaction_base &operator=(const transaction_base &);
};

} // namespace pqxx

#include "pqxx/compiler-internal-post.hxx"
<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
using namespace std;

ListNode* reverse(ListNode *A) {
	if (A == NULL) {
		return NULL;
	}
	else {
		ListNode *temp, *prev, *next;
		temp = A;
		prev = NULL;
		while(temp!=NULL) {
			next = temp->next;
			temp->next = prev;
			prev = temp;
			temp = next;
		}
		A = prev;
		return A;
	}
}

int main() {
	return 0;
}<commit_msg>linkedlist is palindrome<commit_after>#include <iostream>
#include <algorithm>
using namespace std;

ListNode* reverse(ListNode *A) {
	if (A == NULL) {
		return NULL;
	}
	else {
		ListNode *temp, *prev, *next;
		temp = A;
		prev = NULL;
		while(temp!=NULL) {
			next = temp->next;
			temp->next = prev;
			prev = temp;
			temp = next;
		}
		A = prev;
		return A;
	}
}

int Solution::lPalin(ListNode* A) {
	stack	<int> s;
	ListNode *temp = A;
	while(temp!=NULL) {
		s.push(temp->val);
		temp = temp->next;
	}
	temp = A;
	while(temp!=NULL) {
		if(s.top() !=  temp->val) {
			return 0;
		}
		s.pop();
		temp = temp->next;
	}
	return 1;
}

int main() {
	return 0;
}<|endoftext|>


<commit_before>// This file is a part of Simdee, see homepage at http://github.com/tufak/simdee
// This file is distributed under the MIT license.

#ifndef SIMDEE_UTIL_MALLOC_HPP
#define SIMDEE_UTIL_MALLOC_HPP

#include <type_traits>
#include <exception>
#include <cstdlib>
#include <cstdint>
#include "noexcept.hpp"

namespace sd {

    namespace detail {
#if defined(__GLIBCXX__) && (__GLIBCXX__ < 20150422 || __GLIBCXX__ == 20150623 || __GLIBCXX__ == 20150626 || __GLIBCXX__ == 20160803)
        // type_traits is buggered in libstdc++ up until GCC 5
        template <typename T>
        using is_trivially_default_constructible = std::has_trivial_default_constructor<T>;
#else
        template <typename T>
        using is_trivially_default_constructible = std::is_trivially_default_constructible<T>;
#endif

        inline constexpr bool is_pow2(std::size_t x) {
            return x && (x & (x - 1)) == 0;
        }

        template <typename T, std::size_t Align>
        struct aligned_allocator;
        template <typename T, std::size_t Align = alignof(T), bool Switch = (Align > alignof(double))>
        struct alloc;

        template <typename T, std::size_t Align>
        struct alloc<T, Align, false> {
            static T* malloc(std::size_t bytes) {
                return (T*)std::malloc(bytes);
            }
            static void free(T* ptr) {
                std::free(ptr);
            }
            using allocator = std::allocator<T>;
            using deleter = std::default_delete<T>;
        };

        template <typename T, std::size_t Align>
        struct alloc<T, Align, true> {
            static_assert(detail::is_pow2(Align), "alignment must be a power of 2");
            static_assert(Align <= 128, "alignment is too large");
            static_assert(Align > alignof(double), "alignment is too small -- use malloc");

            static T* malloc(std::size_t bytes) {
                auto orig = (uintptr_t)std::malloc(bytes + Align);
                if (orig == 0) return nullptr;
                auto aligned = (orig + Align) & ~(Align - 1);
                auto offset = int8_t(orig - aligned);
                ((int8_t*)aligned)[-1] = offset;
                return (T*)aligned;
            }

            static void free(T* aligned) {
                if (aligned == nullptr) return;
                auto offset = ((int8_t*)aligned)[-1];
                auto orig = uintptr_t(aligned) + offset;
                std::free((void*)orig);
            }

            using allocator = aligned_allocator<T, Align>;

            struct deleter {
                template <typename S>
                void operator()(S* ptr) {
                    free(ptr);
                }
            };
        };

        template <typename T, std::size_t Align>
        struct aligned_allocator {
            using value_type = T;
            using alloc_t = alloc<T, Align>;

            aligned_allocator() = default;

            template <typename S>
            aligned_allocator(const aligned_allocator<S, Align>&) {}

            T* allocate(std::size_t count) const SIMDEE_NOEXCEPT {
                return alloc_t::malloc(sizeof(T) * count);
            }

            void deallocate(T* ptr, std::size_t) const SIMDEE_NOEXCEPT {
                alloc_t::free(ptr);
            }

            void destroy(T* ptr) const SIMDEE_NOEXCEPT_IF(std::is_nothrow_destructible<T>::value) {
                if (!std::is_trivially_destructible<T>::value) {
                    ptr->~T();
                }
                else {
                    no_op(ptr); // just to suppress MSVC warning "ptr not referenced"
                }
            }

            static void no_op(T*) {}

            void construct(T* ptr) const SIMDEE_NOEXCEPT_IF(std::is_nothrow_constructible<T>::value) {
                if (!is_trivially_default_constructible<T>::value) {
                    new (ptr)T;
                }
            }

            template <typename A1, typename... A>
            void construct(T* ptr, A1&& a1, A&&... a2) const {
                new (ptr)T(std::forward<A1>(a1), std::forward<A...>(a2)...);
            }

            // default rebind should do just this, doesn't seem to work in MSVC though
            template <typename S>
            struct rebind {
                using other = aligned_allocator<S, Align>;
            };
        };

        template <typename T, typename U, std::size_t TS, std::size_t US>
        inline bool operator==(const aligned_allocator<T, TS>&, const aligned_allocator<U, US>&) { return true; }
        template <typename T, typename U, std::size_t TS, std::size_t US>
        inline bool operator!=(const aligned_allocator<T, TS>&, const aligned_allocator<U, US>&) { return false; }
    }

    template <typename T, std::size_t Align = alignof(T)>
    using allocator = typename detail::alloc<T, Align>::allocator;
    template <typename T, std::size_t Align = alignof(T)>
    using deleter = typename detail::alloc<T, Align>::deleter;
}

#endif // SIMDEE_UTIL_MALLOC_HPP
<commit_msg>Add missing include<commit_after>// This file is a part of Simdee, see homepage at http://github.com/tufak/simdee
// This file is distributed under the MIT license.

#ifndef SIMDEE_UTIL_MALLOC_HPP
#define SIMDEE_UTIL_MALLOC_HPP

#include <type_traits>
#include <exception>
#include <cstdlib>
#include <cstdint>
#include <memory>
#include "noexcept.hpp"

namespace sd {

    namespace detail {
#if defined(__GLIBCXX__) && (__GLIBCXX__ < 20150422 || __GLIBCXX__ == 20150623 || __GLIBCXX__ == 20150626 || __GLIBCXX__ == 20160803)
        // type_traits is buggered in libstdc++ up until GCC 5
        template <typename T>
        using is_trivially_default_constructible = std::has_trivial_default_constructor<T>;
#else
        template <typename T>
        using is_trivially_default_constructible = std::is_trivially_default_constructible<T>;
#endif

        inline constexpr bool is_pow2(std::size_t x) {
            return x && (x & (x - 1)) == 0;
        }

        template <typename T, std::size_t Align>
        struct aligned_allocator;
        template <typename T, std::size_t Align = alignof(T), bool Switch = (Align > alignof(double))>
        struct alloc;

        template <typename T, std::size_t Align>
        struct alloc<T, Align, false> {
            static T* malloc(std::size_t bytes) {
                return (T*)std::malloc(bytes);
            }
            static void free(T* ptr) {
                std::free(ptr);
            }
            using allocator = std::allocator<T>;
            using deleter = std::default_delete<T>;
        };

        template <typename T, std::size_t Align>
        struct alloc<T, Align, true> {
            static_assert(detail::is_pow2(Align), "alignment must be a power of 2");
            static_assert(Align <= 128, "alignment is too large");
            static_assert(Align > alignof(double), "alignment is too small -- use malloc");

            static T* malloc(std::size_t bytes) {
                auto orig = (uintptr_t)std::malloc(bytes + Align);
                if (orig == 0) return nullptr;
                auto aligned = (orig + Align) & ~(Align - 1);
                auto offset = int8_t(orig - aligned);
                ((int8_t*)aligned)[-1] = offset;
                return (T*)aligned;
            }

            static void free(T* aligned) {
                if (aligned == nullptr) return;
                auto offset = ((int8_t*)aligned)[-1];
                auto orig = uintptr_t(aligned) + offset;
                std::free((void*)orig);
            }

            using allocator = aligned_allocator<T, Align>;

            struct deleter {
                template <typename S>
                void operator()(S* ptr) {
                    free(ptr);
                }
            };
        };

        template <typename T, std::size_t Align>
        struct aligned_allocator {
            using value_type = T;
            using alloc_t = alloc<T, Align>;

            aligned_allocator() = default;

            template <typename S>
            aligned_allocator(const aligned_allocator<S, Align>&) {}

            T* allocate(std::size_t count) const SIMDEE_NOEXCEPT {
                return alloc_t::malloc(sizeof(T) * count);
            }

            void deallocate(T* ptr, std::size_t) const SIMDEE_NOEXCEPT {
                alloc_t::free(ptr);
            }

            void destroy(T* ptr) const SIMDEE_NOEXCEPT_IF(std::is_nothrow_destructible<T>::value) {
                if (!std::is_trivially_destructible<T>::value) {
                    ptr->~T();
                }
                else {
                    no_op(ptr); // just to suppress MSVC warning "ptr not referenced"
                }
            }

            static void no_op(T*) {}

            void construct(T* ptr) const SIMDEE_NOEXCEPT_IF(std::is_nothrow_constructible<T>::value) {
                if (!is_trivially_default_constructible<T>::value) {
                    new (ptr)T;
                }
            }

            template <typename A1, typename... A>
            void construct(T* ptr, A1&& a1, A&&... a2) const {
                new (ptr)T(std::forward<A1>(a1), std::forward<A...>(a2)...);
            }

            // default rebind should do just this, doesn't seem to work in MSVC though
            template <typename S>
            struct rebind {
                using other = aligned_allocator<S, Align>;
            };
        };

        template <typename T, typename U, std::size_t TS, std::size_t US>
        inline bool operator==(const aligned_allocator<T, TS>&, const aligned_allocator<U, US>&) { return true; }
        template <typename T, typename U, std::size_t TS, std::size_t US>
        inline bool operator!=(const aligned_allocator<T, TS>&, const aligned_allocator<U, US>&) { return false; }
    }

    template <typename T, std::size_t Align = alignof(T)>
    using allocator = typename detail::alloc<T, Align>::allocator;
    template <typename T, std::size_t Align = alignof(T)>
    using deleter = typename detail::alloc<T, Align>::deleter;
}

#endif // SIMDEE_UTIL_MALLOC_HPP
<|endoftext|>


<commit_before>#ifndef SIMDIFY_UTIL_INTEGRAL
#define SIMDIFY_UTIL_INTEGRAL

#include "inline.hpp"
#include <cstdint>
#include <type_traits>

namespace simd {

    template <std::size_t Size>
    struct select_sint;
    template <>
    struct select_sint<1> { using type = int8_t; };
    template <>
    struct select_sint<2> { using type = int16_t; };
    template <>
    struct select_sint<4> { using type = int32_t; };
    template <>
    struct select_sint<8> { using type = int64_t; };

    template <std::size_t Size>
    struct select_uint;
    template <>
    struct select_uint<1> { using type = uint8_t; };
    template <>
    struct select_uint<2> { using type = uint16_t; };
    template <>
    struct select_uint<4> { using type = uint32_t; };
    template <>
    struct select_uint<8> { using type = uint64_t; };

    template <std::size_t Size>
    using select_sint_t = typename select_sint<Size>::type;
    template <std::size_t Size>
    using select_uint_t = typename select_uint<Size>::type;

    template <std::size_t x>
    struct is_power_of_2 : std::integral_constant < bool, x && (x & (x - 1)) == 0 > {};

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t div_floor(std::size_t a) { return a / b; }

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t div_ceil(std::size_t a) { return (a + (b - 1)) / b; }

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t div_floor_shift(std::size_t a) {
        if (is_power_of_2<b>::value)
            return a & ~(b - 1);
        else
            return (a / b) * b;
    }

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t div_ceil_shift(std::size_t a) {
        if (is_power_of_2<b>::value)
            return (a + (b - 1)) & ~(b - 1);
        else
            return ((a + (b - 1)) / b) * b;
    }

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t mod(std::size_t a) {
        if (is_power_of_2<b>::value)
            return a & (b - 1);
        else
            return a % b;
    }

}

#endif // SIMDIFY_UTIL_INTEGRAL
<commit_msg>Added sequences for fake iteration using expanded parameter packs<commit_after>#ifndef SIMDIFY_UTIL_INTEGRAL
#define SIMDIFY_UTIL_INTEGRAL

#include "inline.hpp"
#include <cstdint>
#include <type_traits>

namespace simd {

    template <std::size_t Size>
    struct select_sint;
    template <>
    struct select_sint<1> { using type = int8_t; };
    template <>
    struct select_sint<2> { using type = int16_t; };
    template <>
    struct select_sint<4> { using type = int32_t; };
    template <>
    struct select_sint<8> { using type = int64_t; };

    template <std::size_t Size>
    struct select_uint;
    template <>
    struct select_uint<1> { using type = uint8_t; };
    template <>
    struct select_uint<2> { using type = uint16_t; };
    template <>
    struct select_uint<4> { using type = uint32_t; };
    template <>
    struct select_uint<8> { using type = uint64_t; };

    template <std::size_t Size>
    using select_sint_t = typename select_sint<Size>::type;
    template <std::size_t Size>
    using select_uint_t = typename select_uint<Size>::type;

    template <std::size_t x>
    struct is_power_of_2 : std::integral_constant < bool, x && (x & (x - 1)) == 0 > {};

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t div_floor(std::size_t a) { return a / b; }

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t div_ceil(std::size_t a) { return (a + (b - 1)) / b; }

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t div_floor_shift(std::size_t a) {
        if (is_power_of_2<b>::value)
            return a & ~(b - 1);
        else
            return (a / b) * b;
    }

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t div_ceil_shift(std::size_t a) {
        if (is_power_of_2<b>::value)
            return (a + (b - 1)) & ~(b - 1);
        else
            return ((a + (b - 1)) / b) * b;
    }

    template <std::size_t b>
    SIMDIFY_FORCE_INLINE std::size_t mod(std::size_t a) {
        if (is_power_of_2<b>::value)
            return a & (b - 1);
        else
            return a % b;
    }

    template <std::size_t... I>
    struct sequence {};

    template <std::size_t I1, std::size_t I2, std::size_t... I>
    struct make_sequence_impl : make_sequence_impl<I1, I2 - 1, I2, I...> {};

    template <std::size_t I1, std::size_t... I>
    struct make_sequence_impl<I1, I1, I...> { using type = sequence<I1, I...>; };

    template <std::size_t I1, std::size_t I2, typename Enable = void>
    struct make_sequence;

    template <std::size_t I1, std::size_t I2>
    struct make_sequence<I1, I2, typename std::enable_if<(I1 < I2)>::type> : make_sequence_impl<I1, I2 - 1> {};

    template <std::size_t I1, std::size_t I2>
    struct make_sequence<I1, I2, typename std::enable_if<(I1 == I2)>::type> { using type = sequence<>; };

    template <std::size_t I1, std::size_t I2>
    struct make_sequence<I1, I2, typename std::enable_if<(I1 > I2)>::type> {
        static_assert(I1 <= I2, "invalid make_sequence: negative size");
    };

    template <std::size_t I1, std::size_t I2>
    using make_sequence_t = typename make_sequence<I1, I2>::type;

}

#endif // SIMDIFY_UTIL_INTEGRAL
<|endoftext|>


<commit_before>/******************************************************************************

  This source file is part of the Avogadro project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "cmlformat.h"

#include <avogadro/core/elements.h>

#include <pugixml.cpp>

#include <boost/algorithm/string.hpp>

#include <fstream>
#include <streambuf>
#include <iostream>
#include <map>

namespace Avogadro {
namespace Io {

using std::ifstream;
using std::string;
using std::cout;
using std::endl;

using pugi::xml_document;
using pugi::xml_node;
using pugi::xml_attribute;

using namespace Core;

namespace {
class CmlFormatPrivate
{
public:
  CmlFormatPrivate(std::vector<Molecule *> &molecules,
                   pugi::xml_document &document)
    : success(false), molecule(NULL), moleculeNode(NULL)
  {
    // Parse the CML document, and create molecules/elements as necessary.
    moleculeNode = document.child("molecule");
    if (moleculeNode) {
      if (molecules.size() == 0) {
        molecules.resize(1, new Molecule());
      }
      else {
        delete molecules[0];
        molecules[0] = new Molecule();
      }
      // We know there is a molecule, and only one molecule.
      molecule = molecules[0];
      // Parse the various components we know about.
      properties();
      bool atomsExist(atoms());
      bool bondsExist(bonds());
      success = atomsExist && bondsExist;
    }
    else {
      cout << "Error, no molecule node found." << endl;
      success = false;
    }
  }

  void properties()
  {
    xml_attribute attribute;
    xml_node node;
    node = moleculeNode.child("name");
    if (node && node.value())
      molecule->setData("name", std::string(node.child_value()));
    node = moleculeNode.child("identifier");
    if (node && node.value()) {
      attribute = node.attribute("convention");
      if (attribute && std::string(attribute.value()) == "iupac:inchi") {
        attribute = node.attribute("value");
        if (attribute && std::string(attribute.name()) == "value")
          molecule->setData("inchi", std::string(attribute.value()));
      }
    }
  }

  bool atoms()
  {
    xml_node atomArray = moleculeNode.child("atomArray");
    if (!atomArray)
      return false;

    xml_node node = atomArray.child("atom");
    Atom atom;
    while (node) {
      // Step through all of the atom attributes and store them.
      xml_attribute attribute = node.attribute("elementType");
      if (attribute) {
        unsigned char atomicNumber =
          Elements::atomicNumberFromSymbol(attribute.value());
        atom = molecule->addAtom(atomicNumber);
      }
      else {
        // There is no element data, this atom node is corrupt.
        cout << "Warning, corrupt element node found." << endl;
        return false;
      }

      attribute = node.attribute("id");
      if (attribute)
        atomIds[std::string(attribute.value())] = atom.index();
      else // Atom nodes must have IDs - bail.
        return false;

      // Check for 3D geometry.
      attribute = node.attribute("x3");
      if (attribute) {
        xml_attribute y3 = node.attribute("y3");
        xml_attribute z3 = node.attribute("z3");
        if (y3 && z3) {
          // It looks like we have a valid 3D position.
          Vector3 position(strtod(attribute.value(), 0),
                           strtod(y3.value(), 0),
                           strtod(z3.value(), 0));
          atom.setPosition3d(position);
        }
        else {
          // Corrupt 3D position supplied for atom.
          return false;
        }
      }

      // Check for 2D geometry.
      attribute = node.attribute("x2");
      if (attribute) {
        xml_attribute y2 = node.attribute("y2");
        if (y2) {
          Vector2 position(strtod(attribute.value(), 0),
                           strtod(y2.value(), 0));
          atom.setPosition2d(position);
        }
        else {
          // Corrupt 2D position supplied for atom.
          return false;
        }
      }

      // Move on to the next atom node (if there is one).
      node = node.next_sibling("atom");
    }
    return true;
  }

  bool bonds()
  {
    xml_node bondArray = moleculeNode.child("bondArray");
    if (!bondArray)
      return false;

    xml_node node = bondArray.child("bond");

    while (node) {
      xml_attribute attribute = node.attribute("atomRefs2");
      Bond bond;
      if (attribute) {
        // Should contain two elements separated by a space.
        std::string refs(attribute.value());
        std::vector<std::string> tokens;
        boost::split(tokens, refs, boost::is_any_of(" "));
        if (tokens.size() != 2) // Corrupted file/input we don't understand
          return false;
        std::map<std::string, size_t>::const_iterator begin, end;
        begin = atomIds.find(tokens[0]);
        end = atomIds.find(tokens[1]);
        if (begin != atomIds.end() && end != atomIds.end()
            && begin->second < molecule->atomCount()
            && end->second < molecule->atomCount()) {
          bond = molecule->addBond(molecule->atom(begin->second),
                                   molecule->atom(end->second));
        }
        else { // Couldn't parse the bond begin and end.
          return false;
        }
      }

      attribute = node.attribute("order");
      if (attribute)
        bond.setOrder(atoi(attribute.value()));

      // Move on to the next bond node (if there is one).
      node = node.next_sibling("bond");
    }

    return true;
  }

  bool success;
  Molecule *molecule;
  xml_node moleculeNode;
  std::map<std::string, size_t> atomIds;
};
}

CmlFormat::CmlFormat()
{
}

CmlFormat::~CmlFormat()
{
}

bool CmlFormat::readFile(const std::string &fileName)
{
  // Read the file into a string.
  std::ifstream file(fileName.c_str());
  if (!file.is_open()) {
    cout << "Error opening file: " << fileName << endl;
    return false;
  }

  xml_document document;
  pugi::xml_parse_result result = document.load(file);
  if (!result) {
    cout << "Error parsing XML: " << result.description() << endl;
    return false;
  }

  CmlFormatPrivate parser(m_molecules, document);

  return result == true;
}

bool CmlFormat::writeFile(const std::string &)
{
  return true;
}

Molecule * CmlFormat::molecule(size_t index)
{
  if (index < m_molecules.size())
    return m_molecules[index];
  else
    return 0;
}

} // end Io namespace
} // end Avogadro namespace
<commit_msg>Return true if we get this far, already checked for errors<commit_after>/******************************************************************************

  This source file is part of the Avogadro project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "cmlformat.h"

#include <avogadro/core/elements.h>

#include <pugixml.cpp>

#include <boost/algorithm/string.hpp>

#include <fstream>
#include <streambuf>
#include <iostream>
#include <map>

namespace Avogadro {
namespace Io {

using std::ifstream;
using std::string;
using std::cout;
using std::endl;

using pugi::xml_document;
using pugi::xml_node;
using pugi::xml_attribute;

using namespace Core;

namespace {
class CmlFormatPrivate
{
public:
  CmlFormatPrivate(std::vector<Molecule *> &molecules,
                   pugi::xml_document &document)
    : success(false), molecule(NULL), moleculeNode(NULL)
  {
    // Parse the CML document, and create molecules/elements as necessary.
    moleculeNode = document.child("molecule");
    if (moleculeNode) {
      if (molecules.size() == 0) {
        molecules.resize(1, new Molecule());
      }
      else {
        delete molecules[0];
        molecules[0] = new Molecule();
      }
      // We know there is a molecule, and only one molecule.
      molecule = molecules[0];
      // Parse the various components we know about.
      properties();
      bool atomsExist(atoms());
      bool bondsExist(bonds());
      success = atomsExist && bondsExist;
    }
    else {
      cout << "Error, no molecule node found." << endl;
      success = false;
    }
  }

  void properties()
  {
    xml_attribute attribute;
    xml_node node;
    node = moleculeNode.child("name");
    if (node && node.value())
      molecule->setData("name", std::string(node.child_value()));
    node = moleculeNode.child("identifier");
    if (node && node.value()) {
      attribute = node.attribute("convention");
      if (attribute && std::string(attribute.value()) == "iupac:inchi") {
        attribute = node.attribute("value");
        if (attribute && std::string(attribute.name()) == "value")
          molecule->setData("inchi", std::string(attribute.value()));
      }
    }
  }

  bool atoms()
  {
    xml_node atomArray = moleculeNode.child("atomArray");
    if (!atomArray)
      return false;

    xml_node node = atomArray.child("atom");
    Atom atom;
    while (node) {
      // Step through all of the atom attributes and store them.
      xml_attribute attribute = node.attribute("elementType");
      if (attribute) {
        unsigned char atomicNumber =
          Elements::atomicNumberFromSymbol(attribute.value());
        atom = molecule->addAtom(atomicNumber);
      }
      else {
        // There is no element data, this atom node is corrupt.
        cout << "Warning, corrupt element node found." << endl;
        return false;
      }

      attribute = node.attribute("id");
      if (attribute)
        atomIds[std::string(attribute.value())] = atom.index();
      else // Atom nodes must have IDs - bail.
        return false;

      // Check for 3D geometry.
      attribute = node.attribute("x3");
      if (attribute) {
        xml_attribute y3 = node.attribute("y3");
        xml_attribute z3 = node.attribute("z3");
        if (y3 && z3) {
          // It looks like we have a valid 3D position.
          Vector3 position(strtod(attribute.value(), 0),
                           strtod(y3.value(), 0),
                           strtod(z3.value(), 0));
          atom.setPosition3d(position);
        }
        else {
          // Corrupt 3D position supplied for atom.
          return false;
        }
      }

      // Check for 2D geometry.
      attribute = node.attribute("x2");
      if (attribute) {
        xml_attribute y2 = node.attribute("y2");
        if (y2) {
          Vector2 position(strtod(attribute.value(), 0),
                           strtod(y2.value(), 0));
          atom.setPosition2d(position);
        }
        else {
          // Corrupt 2D position supplied for atom.
          return false;
        }
      }

      // Move on to the next atom node (if there is one).
      node = node.next_sibling("atom");
    }
    return true;
  }

  bool bonds()
  {
    xml_node bondArray = moleculeNode.child("bondArray");
    if (!bondArray)
      return false;

    xml_node node = bondArray.child("bond");

    while (node) {
      xml_attribute attribute = node.attribute("atomRefs2");
      Bond bond;
      if (attribute) {
        // Should contain two elements separated by a space.
        std::string refs(attribute.value());
        std::vector<std::string> tokens;
        boost::split(tokens, refs, boost::is_any_of(" "));
        if (tokens.size() != 2) // Corrupted file/input we don't understand
          return false;
        std::map<std::string, size_t>::const_iterator begin, end;
        begin = atomIds.find(tokens[0]);
        end = atomIds.find(tokens[1]);
        if (begin != atomIds.end() && end != atomIds.end()
            && begin->second < molecule->atomCount()
            && end->second < molecule->atomCount()) {
          bond = molecule->addBond(molecule->atom(begin->second),
                                   molecule->atom(end->second));
        }
        else { // Couldn't parse the bond begin and end.
          return false;
        }
      }

      attribute = node.attribute("order");
      if (attribute)
        bond.setOrder(atoi(attribute.value()));

      // Move on to the next bond node (if there is one).
      node = node.next_sibling("bond");
    }

    return true;
  }

  bool success;
  Molecule *molecule;
  xml_node moleculeNode;
  std::map<std::string, size_t> atomIds;
};
}

CmlFormat::CmlFormat()
{
}

CmlFormat::~CmlFormat()
{
}

bool CmlFormat::readFile(const std::string &fileName)
{
  // Read the file into a string.
  std::ifstream file(fileName.c_str());
  if (!file.is_open()) {
    cout << "Error opening file: " << fileName << endl;
    return false;
  }

  xml_document document;
  pugi::xml_parse_result result = document.load(file);
  if (!result) {
    cout << "Error parsing XML: " << result.description() << endl;
    return false;
  }

  CmlFormatPrivate parser(m_molecules, document);

  return true;
}

bool CmlFormat::writeFile(const std::string &)
{
  return true;
}

Molecule * CmlFormat::molecule(size_t index)
{
  if (index < m_molecules.size())
    return m_molecules[index];
  else
    return 0;
}

} // end Io namespace
} // end Avogadro namespace
<|endoftext|>


<commit_before>#include <fstream>
#include <vector>
#include "allocore/system/al_Time.hpp"
#include "allocore/graphics/al_OpenGL.hpp"
#include "allocore/graphics/al_Screenshot.hpp"

namespace al{

bool Screenshot::save(unsigned w, unsigned h, const std::string& filePath){
	std::ofstream fs;
	auto derivedFilePath = filePath;
	if(derivedFilePath.empty()){
		derivedFilePath = mPath + "screenshot_" + timecodeNow("D_HMS") + "." + mExt;
	}

	fs.open(derivedFilePath);

	if(!fs.is_open()) return false;

	std::vector<unsigned char> pix(w*h*3, 0);
	glReadPixels(0,0, w,h, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)&pix[0]);
	//printf("%d %d %d\n", pix[0], pix[1], pix[2]);

	auto lsB = [](unsigned x){ return (unsigned char)(x&255); };
	auto msB = [](unsigned x){ return (unsigned char)((x>>8)&255); };

	// TGA (simplest format, widely supported)
	// http://www.paulbourke.net/dataformats/tga/
	unsigned char hdr[18] = {
		0,			// image ID length
		0,			// color map
		2,			// uncompressed true-color
		0,0,0,0,0,	// color map
		0,0, 0,0,	// image origin
		lsB(w), msB(w), lsB(h), msB(h), // width,height in pixels
		24,			// bits/pixel
		0			// image descriptor
	};
	fs.write((char*)hdr, sizeof(hdr));
	// Annoyingly, TGA is little endian, so we have to write BGR
	for(unsigned i=0; i<pix.size(); i+=3) std::swap(pix[i], pix[i+2]);
	fs.write((char*)&pix[0], pix.size());

	// Other potential formats to support in future...

	// PNG (really complicated)
	//unsigned char hdr[] = {137,'P','N','G',13,10,26,10};

	// PBM (simple, but ASCII format so big files)

	/* TIFF (a bit complicated)
	// http://paulbourke.net/dataformats/tiff/
	// http://www.fileformat.info/format/tiff/corion.htm
	fs.open(RUN_MAIN_SOURCE_PATH "screenshot.tif.txt");
	unsigned char hdr[] = {
		'M','M',0,42,0,0,0,8, // big endian
		0x01,0x00, 0,3, 0,0,0,1, msB(w), lsB(w), 0,0), // width
		0x01,0x01, 0,3, 0,0,0,1, msB(h), lsB(h), 0,0), // height
		0x01,0x02, 0,3, 0,0,0,1, 0, 24, 0,0, // bits/sample
		0x01,0x03, 0,3, 0,0,0,1, 0,  1, 0,0, // compression
		0x01,0x06, 0,3, 0,0,0,1, 0,  2, 0,0, // RGB
	};
	//fs.write((char*)hdr,8);
	//*/

	return true;
}

} // al::
<commit_msg>Screenshot: open file in binary mode<commit_after>#include <fstream>
#include <vector>
#include "allocore/system/al_Time.hpp"
#include "allocore/graphics/al_OpenGL.hpp"
#include "allocore/graphics/al_Screenshot.hpp"

namespace al{

bool Screenshot::save(unsigned w, unsigned h, const std::string& filePath){
	auto derivedFilePath = filePath;
	if(derivedFilePath.empty()){
		derivedFilePath = mPath + "screenshot_" + timecodeNow("D_HMS") + "." + mExt;
	}

	std::ofstream fs(derivedFilePath, std::ofstream::out | std::ofstream::binary);

	if(!fs.is_open()) return false;

	std::vector<unsigned char> pix(w*h*3, 0);
	glReadPixels(0,0, w,h, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)&pix[0]);
	//printf("%d %d %d\n", pix[0], pix[1], pix[2]);

	auto lsB = [](unsigned x){ return (unsigned char)(x&255); };
	auto msB = [](unsigned x){ return (unsigned char)((x>>8)&255); };

	// TGA (simplest format, widely supported)
	// http://www.paulbourke.net/dataformats/tga/
	unsigned char hdr[18] = {
		0,			// image ID length
		0,			// color map
		2,			// uncompressed true-color
		0,0,0,0,0,	// color map
		0,0, 0,0,	// image origin
		lsB(w), msB(w), lsB(h), msB(h), // width,height in pixels
		24,			// bits/pixel
		0			// descriptor: 00vhaaaa - v/h vert/hor flip, a alpha bits
	};
	fs.write((char*)hdr, sizeof(hdr));
	// Annoyingly, TGA is little endian, so we have to write BGR
	for(unsigned i=0; i<pix.size(); i+=3) std::swap(pix[i], pix[i+2]);
	fs.write((char*)&pix[0], pix.size());

	// Other potential formats to support in future...

	// PNG (really complicated)
	//unsigned char hdr[] = {137,'P','N','G',13,10,26,10};

	// PBM (simple, but ASCII format so big files)

	/* TIFF (a bit complicated)
	// http://paulbourke.net/dataformats/tiff/
	// http://www.fileformat.info/format/tiff/corion.htm
	fs.open(RUN_MAIN_SOURCE_PATH "screenshot.tif.txt");
	unsigned char hdr[] = {
		'M','M',0,42,0,0,0,8, // big endian
		0x01,0x00, 0,3, 0,0,0,1, msB(w), lsB(w), 0,0), // width
		0x01,0x01, 0,3, 0,0,0,1, msB(h), lsB(h), 0,0), // height
		0x01,0x02, 0,3, 0,0,0,1, 0, 24, 0,0, // bits/sample
		0x01,0x03, 0,3, 0,0,0,1, 0,  1, 0,0, // compression
		0x01,0x06, 0,3, 0,0,0,1, 0,  2, 0,0, // RGB
	};
	//fs.write((char*)hdr,8);
	//*/

	return true;
}

} // al::
<|endoftext|>


<commit_before>#include "analyzing_dataflash_message_handler.h"

void Analyzing_DataFlash_Message_Handler::handle_format_message_received(const char *name, const struct log_Format &format, const char *msg) {
    uint8_t new_msg_type = ((struct log_Format*)(msg))->type;
    if (streq(name, "AHR2")) {
        ahr2_handler= new LA_MsgHandler_AHR2(name, format, _analyze, _vehicle);
        handlers[new_msg_type] = ahr2_handler;
        if (have_pos) {
            ahr2_handler->set_canonical_for_position(false);
        }
        if (have_orgn) {
            ahr2_handler->set_canonical_for_origin(false);
        }
    } else if (streq(name, "ATT")) {
        handlers[new_msg_type] = new LA_MsgHandler_ATT(name, format, _analyze, _vehicle);
    } else if (streq(name, "BARO")) {
        handlers[new_msg_type] = new LA_MsgHandler_BARO(name, format, _analyze, _vehicle);
    } else if (streq(name, "EKF1")) {
        handlers[new_msg_type] = new LA_MsgHandler_EKF1(name, format, _analyze, _vehicle);
    } else if (streq(name, "EKF4")) {
        handlers[new_msg_type] = new LA_MsgHandler_EKF4(name, format, _analyze, _vehicle);
    } else if (streq(name, "ERR")) {
        handlers[new_msg_type] = new LA_MsgHandler_ERR(name, format, _analyze, _vehicle);
    } else if (streq(name, "EV")) {
        handlers[new_msg_type] = new LA_MsgHandler_EV(name, format, _analyze, _vehicle);
    } else if (streq(name, "GPS")) {
        handlers[new_msg_type] = new LA_MsgHandler_GPS(name, format, _analyze, _vehicle);
    } else if (streq(name, "GPS2")) {
        handlers[new_msg_type] = new LA_MsgHandler_GPS(name, format, _analyze, _vehicle);
    } else if (streq(name, "MAG")) {
        handlers[new_msg_type] = new LA_MsgHandler_MAG(name, format, _analyze, _vehicle);
    } else if (streq(name, "MAG2")) {
        handlers[new_msg_type] = new LA_MsgHandler_MAG(name, format, _analyze, _vehicle);
    } else if (streq(name, "MAG3")) {
        handlers[new_msg_type] = new LA_MsgHandler_MAG(name, format, _analyze, _vehicle);
    } else if (streq(name, "MSG")) {
        handlers[new_msg_type] = new LA_MsgHandler_MSG(name, format, _analyze, _vehicle);
    } else if (streq(name, "ORGN")) {
        have_orgn = true;
        handlers[new_msg_type] = new LA_MsgHandler_ORGN(name, format, _analyze, _vehicle);
        if (ahr2_handler != NULL) {
            ahr2_handler->set_canonical_for_origin(false);
        }
    } else if (streq(name, "PARM")) {
        handlers[new_msg_type] = new LA_MsgHandler_PARM(name, format, _analyze, _vehicle);
    } else if (streq(name, "PM")) {
        handlers[new_msg_type] = new LA_MsgHandler_PM(name, format, _analyze, _vehicle);
    } else if (streq(name, "POS")) {
        handlers[new_msg_type] = new LA_MsgHandler_POS(name, format, _analyze, _vehicle);
        have_pos = true;
        if (ahr2_handler != NULL) {
            ahr2_handler->set_canonical_for_position(false);
        }
    } else if (streq(name, "RCOU")) {
        handlers[new_msg_type] = new LA_MsgHandler_RCOU(name, format, _analyze, _vehicle);
    } else if (streq(name, "STAT")) {
        handlers[new_msg_type] = new LA_MsgHandler_STAT(name, format, _analyze, _vehicle);
    } else if (streq(name, "VIBE")) {
        handlers[new_msg_type] = new LA_MsgHandler_VIBE(name, format, _analyze, _vehicle);
    } else {
        return;
    }
    if (handlers[new_msg_type] == NULL) {
        ::fprintf(stderr, "Failed to construct");
        abort();
    }
}

void Analyzing_DataFlash_Message_Handler::handle_message_received(const struct log_Format &format, const uint8_t *msg)
{

    LA_MsgHandler *handler = handlers[format.type];
    if (handler == NULL) {
        // ::fprintf(stderr, "No handler for (%u) (%s)\n", format.type, format_names[format.type]);
        return;
    }

    handler->process(msg);
}

void Analyzing_DataFlash_Message_Handler::end_of_log(uint32_t packet_count, uint64_t bytes_dropped UNUSED)
{
    _analyze->end_of_log(packet_count);
}
<commit_msg>analyzing_dataflash_message_handler: handle IMU messages<commit_after>#include "analyzing_dataflash_message_handler.h"

void Analyzing_DataFlash_Message_Handler::handle_format_message_received(const char *name, const struct log_Format &format, const char *msg) {
    uint8_t new_msg_type = ((struct log_Format*)(msg))->type;
    if (streq(name, "AHR2")) {
        ahr2_handler= new LA_MsgHandler_AHR2(name, format, _analyze, _vehicle);
        handlers[new_msg_type] = ahr2_handler;
        if (have_pos) {
            ahr2_handler->set_canonical_for_position(false);
        }
        if (have_orgn) {
            ahr2_handler->set_canonical_for_origin(false);
        }
    } else if (streq(name, "ATT")) {
        handlers[new_msg_type] = new LA_MsgHandler_ATT(name, format, _analyze, _vehicle);
    } else if (streq(name, "BARO")) {
        handlers[new_msg_type] = new LA_MsgHandler_BARO(name, format, _analyze, _vehicle);
    } else if (streq(name, "EKF1")) {
        handlers[new_msg_type] = new LA_MsgHandler_EKF1(name, format, _analyze, _vehicle);
    } else if (streq(name, "EKF4")) {
        handlers[new_msg_type] = new LA_MsgHandler_EKF4(name, format, _analyze, _vehicle);
    } else if (streq(name, "ERR")) {
        handlers[new_msg_type] = new LA_MsgHandler_ERR(name, format, _analyze, _vehicle);
    } else if (streq(name, "EV")) {
        handlers[new_msg_type] = new LA_MsgHandler_EV(name, format, _analyze, _vehicle);
    } else if (streq(name, "GPS")) {
        handlers[new_msg_type] = new LA_MsgHandler_GPS(name, format, _analyze, _vehicle);
    } else if (streq(name, "GPS2")) {
        handlers[new_msg_type] = new LA_MsgHandler_GPS(name, format, _analyze, _vehicle);
    } else if (streq(name, "IMU")) {
        handlers[new_msg_type] = new LA_MsgHandler_IMU(name, format, _analyze, _vehicle);
    } else if (streq(name, "IMU2")) {
        handlers[new_msg_type] = new LA_MsgHandler_IMU(name, format, _analyze, _vehicle);
    } else if (streq(name, "IMU3")) {
        handlers[new_msg_type] = new LA_MsgHandler_IMU(name, format, _analyze, _vehicle);
    } else if (streq(name, "MAG")) {
        handlers[new_msg_type] = new LA_MsgHandler_MAG(name, format, _analyze, _vehicle);
    } else if (streq(name, "MAG2")) {
        handlers[new_msg_type] = new LA_MsgHandler_MAG(name, format, _analyze, _vehicle);
    } else if (streq(name, "MAG3")) {
        handlers[new_msg_type] = new LA_MsgHandler_MAG(name, format, _analyze, _vehicle);
    } else if (streq(name, "MSG")) {
        handlers[new_msg_type] = new LA_MsgHandler_MSG(name, format, _analyze, _vehicle);
    } else if (streq(name, "ORGN")) {
        have_orgn = true;
        handlers[new_msg_type] = new LA_MsgHandler_ORGN(name, format, _analyze, _vehicle);
        if (ahr2_handler != NULL) {
            ahr2_handler->set_canonical_for_origin(false);
        }
    } else if (streq(name, "PARM")) {
        handlers[new_msg_type] = new LA_MsgHandler_PARM(name, format, _analyze, _vehicle);
    } else if (streq(name, "PM")) {
        handlers[new_msg_type] = new LA_MsgHandler_PM(name, format, _analyze, _vehicle);
    } else if (streq(name, "POS")) {
        handlers[new_msg_type] = new LA_MsgHandler_POS(name, format, _analyze, _vehicle);
        have_pos = true;
        if (ahr2_handler != NULL) {
            ahr2_handler->set_canonical_for_position(false);
        }
    } else if (streq(name, "RCOU")) {
        handlers[new_msg_type] = new LA_MsgHandler_RCOU(name, format, _analyze, _vehicle);
    } else if (streq(name, "STAT")) {
        handlers[new_msg_type] = new LA_MsgHandler_STAT(name, format, _analyze, _vehicle);
    } else if (streq(name, "VIBE")) {
        handlers[new_msg_type] = new LA_MsgHandler_VIBE(name, format, _analyze, _vehicle);
    } else {
        return;
    }
    if (handlers[new_msg_type] == NULL) {
        ::fprintf(stderr, "Failed to construct");
        abort();
    }
}

void Analyzing_DataFlash_Message_Handler::handle_message_received(const struct log_Format &format, const uint8_t *msg)
{

    LA_MsgHandler *handler = handlers[format.type];
    if (handler == NULL) {
        // ::fprintf(stderr, "No handler for (%u) (%s)\n", format.type, format_names[format.type]);
        return;
    }

    handler->process(msg);
}

void Analyzing_DataFlash_Message_Handler::end_of_log(uint32_t packet_count, uint64_t bytes_dropped UNUSED)
{
    _analyze->end_of_log(packet_count);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>

#include <setjmp.h>

#include <readline/readline.h>
#include <readline/history.h>

#include "shared.hh"
#include "eval.hh"
#include "eval-inline.hh"
#include "store-api.hh"
#include "common-opts.hh"

using namespace std;
using namespace nix;

string programId = "nix-repl";

struct NixRepl
{
    string curDir;
    EvalState state;

    StaticEnv staticEnv;
    Env * env;
    int displ;

    NixRepl();
    void mainLoop();
    void processLine(string line);
    void addAttrsToScope(Value & attrs);
    void addVarToScope(const Symbol & name, Value * v);
    Expr * parseString(string s);
    void evalString(string s, Value & v);
};

void printHelp()
{
    std::cout << "Usage: nix-repl\n";
}

/* Apparently, the only way to get readline() to return on Ctrl-C
   (SIGINT) is to use siglongjmp().  That's fucked up... */
static sigjmp_buf sigintJmpBuf;

static void sigintHandler(int signo)
{
    siglongjmp(sigintJmpBuf, 1);
}

bool getLine(string & line)
{
    struct sigaction act, old;
    act.sa_handler = sigintHandler;
    sigfillset(&act.sa_mask);
    act.sa_flags = 0;
    if (sigaction(SIGINT, &act, &old))
        throw SysError("installing handler for SIGINT");

    if (sigsetjmp(sigintJmpBuf, 1))
        line = "";
    else {
        char * s = readline("nix-repl> ");
        if (!s) return false;
        line = chomp(string(s));
        free(s);
        if (line != "") {
            add_history(line.c_str());
            append_history(1, 0);
        }
    }

    _isInterrupted = 0;

    if (sigaction(SIGINT, &old, 0))
        throw SysError("restoring handler for SIGINT");

    return true;
}

string removeWhitespace(string s)
{
    s = chomp(s);
    size_t n = s.find_first_not_of(" \n\r\t");
    if (n != string::npos) s = string(s, n);
    return s;
}

NixRepl::NixRepl()
    : staticEnv(false, &state.staticBaseEnv)
{
    curDir = absPath(".");

    env = &state.allocEnv(32768);
    env->up = &state.baseEnv;
    displ = 0;

    store = openStore();
}

void NixRepl::mainLoop()
{
    std::cerr << "Welcome to Nix version " << NIX_VERSION << ". Type :? for help." << std::endl << std::endl;

    using_history();
    read_history(0);

    while (true) {
        string line;
        if (!getLine(line)) break;

        try {
            processLine(removeWhitespace(line));
        } catch (Error & e) {
            printMsg(lvlError, e.msg());
        }

        std::cout << std::endl;
    }

    std::cout << std::endl;
}

void NixRepl::processLine(string line)
{
    if (line == "") return;

    if (string(line, 0, 2) == ":a") {
        Value v;
        evalString(string(line, 2), v);
        addAttrsToScope(v);
    }

    else if (string(line, 0, 2) == ":l") {
        state.resetFileCache();
        Path path = lookupFileArg(state, removeWhitespace(string(line, 2)));
        Value v, v2;
        state.evalFile(path, v);
        Bindings bindings;
        state.autoCallFunction(bindings, v, v2);
        addAttrsToScope(v2);
    }

    else if (string(line, 0, 2) == ":t") {
        Value v;
        evalString(string(line, 2), v);
        std::cout << showType(v) << std::endl;
    }

    else if (string(line, 0, 1) == ":") {
        throw Error(format("unknown command ‘%1%’") % string(line, 0, 2));
    }

    else {
        Value v;
        evalString(line, v);
        state.strictForceValue(v);
        std::cout << v << std::endl;
    }
}

void NixRepl::addAttrsToScope(Value & attrs)
{
    state.forceAttrs(attrs);
    foreach (Bindings::iterator, i, *attrs.attrs)
        addVarToScope(i->name, i->value);
}

void NixRepl::addVarToScope(const Symbol & name, Value * v)
{
    staticEnv.vars[name] = displ;
    env->values[displ++] = v;
}

Expr * NixRepl::parseString(string s)
{
    Expr * e = state.parseExprFromString(s, curDir, staticEnv);
    return e;
}

void NixRepl::evalString(string s, Value & v)
{
    Expr * e = parseString(s);
    e->eval(state, *env, v);
    state.forceValue(v);
}

void run(nix::Strings args)
{
    NixRepl repl;
    repl.mainLoop();
}
<commit_msg>Don't exit on SIGINT during evaluation<commit_after>#include <iostream>
#include <cstdlib>

#include <setjmp.h>

#include <readline/readline.h>
#include <readline/history.h>

#include "shared.hh"
#include "eval.hh"
#include "eval-inline.hh"
#include "store-api.hh"
#include "common-opts.hh"

using namespace std;
using namespace nix;

string programId = "nix-repl";

struct NixRepl
{
    string curDir;
    EvalState state;

    StaticEnv staticEnv;
    Env * env;
    int displ;

    NixRepl();
    void mainLoop();
    void processLine(string line);
    void addAttrsToScope(Value & attrs);
    void addVarToScope(const Symbol & name, Value * v);
    Expr * parseString(string s);
    void evalString(string s, Value & v);
};

void printHelp()
{
    std::cout << "Usage: nix-repl\n";
}

/* Apparently, the only way to get readline() to return on Ctrl-C
   (SIGINT) is to use siglongjmp().  That's fucked up... */
static sigjmp_buf sigintJmpBuf;

static void sigintHandler(int signo)
{
    siglongjmp(sigintJmpBuf, 1);
}

bool getLine(string & line)
{
    struct sigaction act, old;
    act.sa_handler = sigintHandler;
    sigfillset(&act.sa_mask);
    act.sa_flags = 0;
    if (sigaction(SIGINT, &act, &old))
        throw SysError("installing handler for SIGINT");

    if (sigsetjmp(sigintJmpBuf, 1))
        line = "";
    else {
        char * s = readline("nix-repl> ");
        if (!s) return false;
        line = chomp(string(s));
        free(s);
        if (line != "") {
            add_history(line.c_str());
            append_history(1, 0);
        }
    }

    _isInterrupted = 0;

    if (sigaction(SIGINT, &old, 0))
        throw SysError("restoring handler for SIGINT");

    return true;
}

string removeWhitespace(string s)
{
    s = chomp(s);
    size_t n = s.find_first_not_of(" \n\r\t");
    if (n != string::npos) s = string(s, n);
    return s;
}

NixRepl::NixRepl()
    : staticEnv(false, &state.staticBaseEnv)
{
    curDir = absPath(".");

    env = &state.allocEnv(32768);
    env->up = &state.baseEnv;
    displ = 0;

    store = openStore();
}

void NixRepl::mainLoop()
{
    std::cerr << "Welcome to Nix version " << NIX_VERSION << ". Type :? for help." << std::endl << std::endl;

    using_history();
    read_history(0);

    while (true) {
        string line;
        if (!getLine(line)) break;

        try {
            processLine(removeWhitespace(line));
        } catch (Error & e) {
            printMsg(lvlError, e.msg());
        } catch (Interrupted & e) {
            printMsg(lvlError, e.msg());
        }

        std::cout << std::endl;
    }

    std::cout << std::endl;
}

void NixRepl::processLine(string line)
{
    if (line == "") return;

    if (string(line, 0, 2) == ":a") {
        Value v;
        evalString(string(line, 2), v);
        addAttrsToScope(v);
    }

    else if (string(line, 0, 2) == ":l") {
        state.resetFileCache();
        Path path = lookupFileArg(state, removeWhitespace(string(line, 2)));
        Value v, v2;
        state.evalFile(path, v);
        Bindings bindings;
        state.autoCallFunction(bindings, v, v2);
        addAttrsToScope(v2);
    }

    else if (string(line, 0, 2) == ":t") {
        Value v;
        evalString(string(line, 2), v);
        std::cout << showType(v) << std::endl;
    }

    else if (string(line, 0, 1) == ":") {
        throw Error(format("unknown command ‘%1%’") % string(line, 0, 2));
    }

    else {
        Value v;
        evalString(line, v);
        state.strictForceValue(v);
        std::cout << v << std::endl;
    }
}

void NixRepl::addAttrsToScope(Value & attrs)
{
    state.forceAttrs(attrs);
    foreach (Bindings::iterator, i, *attrs.attrs)
        addVarToScope(i->name, i->value);
    printMsg(lvlError, format("added %1% variables") % attrs.attrs->size());
}

void NixRepl::addVarToScope(const Symbol & name, Value * v)
{
    staticEnv.vars[name] = displ;
    env->values[displ++] = v;
}

Expr * NixRepl::parseString(string s)
{
    Expr * e = state.parseExprFromString(s, curDir, staticEnv);
    return e;
}

void NixRepl::evalString(string s, Value & v)
{
    Expr * e = parseString(s);
    e->eval(state, *env, v);
    state.forceValue(v);
}

void run(nix::Strings args)
{
    NixRepl repl;
    repl.mainLoop();
}
<|endoftext|>


<commit_before>

#include "../libmmdpi/mmdpi.h"
//#include "../gl_xfile/gl_xfile.h"

#ifdef _WIN32
#	ifdef _DEBUG
#		pragma comment( lib, "../Debug/libmmdpi.lib" )
#	else
#		pragma comment( lib, "../Release/libmmdpi.lib" )
#	endif
#endif

//#ifdef _DEBUG
//	#pragma comment( lib, "../Debug/gl_xfile.lib" )
//#else
//	#pragma comment( lib, "../Release/gl_xfile.lib" )
//#endif

#include <iostream>
#include "GL/glut.h"

const int		_zoom_default_	= -1024 * 2 * 0.1f;// * 16;
float			_y_pos_			= 11 * 0.1f;
static mmdpi*	p = NULL;
int				_fps_			= 30;
int 			motion_flag = 0;
float			Zoom;
float			Rotate;

float			RotationAxis[ 3 ];

int				screen_width, screen_height;

int				Argc;
const char**			Argv;

#include "fps.h"

Fps* fps = NULL;

void end( void );

void display( void )
{
	GLfloat light0pos[] = { 4.0, 16.0, -8.0, 1.0 };

	glEnable( GL_DEPTH_TEST );

	glEnable( GL_LIGHTING );
	glEnable( GL_LIGHT0 );

	//glClearColor( 0.0, 0.0, 1.0, 1.0 );	//	bule
	//glClearColor( 0.0, 0.2, 0.0, 1.0 );	//	bule
	//glClearColor( 0.0, 0.0, 0.0, 1.0 );	//	black
	glClearColor( 1.0, 1.0, 1.0, 1.0 );	//	white
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	glColor3d( 1.0, 0.0, 0.0 );

	glLightfv( GL_LIGHT0, GL_POSITION, light0pos );

	float diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
	float ambient[] = { 1.0, 1.0, 1.0, 1.0 };
	glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse );
	glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient );

	static float rot = 0.0f;

	// カメラ
	glMatrixMode( GL_MODELVIEW );

	glPushMatrix();
	{
	//	glRotatef( rot, 1, 0, 0 );
		//glRotatef( 3.14f, 0, 1, 0 );
		//glRotatef( rot, 0, 1, 0 );
		//glTranslatef( 0, 0, Zoom );

		//glutSolidTeapot( 0.5 );

		glRotatef( RotationAxis[ 0 ], 1, 0, 0 );
		glRotatef( RotationAxis[ 1 ], 0, 1, 0 );

		glScalef( 0.1f, 0.1f, 0.1f );
		p->draw();
	}
	glPopMatrix();

	//rot += 0.1f;

	glutSwapBuffers();
}

void keyboard( unsigned char key, int x, int y )
{
	switch( key )
	{
	case 'q':
	case 'Q':
	case '\033':  /* '\033' は ESC の ASCII コード */
		end();
		exit( 0 );
	case 'u':
		//	fps
		if( fps->get_fps() < 120 )
		{
			fps->set_fps( fps->get_fps() + 5 );
			p->set_fps( fps->get_fps() );
		}
		break;
	case 'd':
		if( fps->get_fps() > 10 )
		{
			fps->set_fps( fps->get_fps() - 5 );
			p->set_fps( fps->get_fps() );
		}
		break;
	return ;

	default:
		break;
	}
}

void sp_keyboard( int key, int x, int y )
{
	//static float	rotate	= 0;
	//static float	zoom	= _zoom_default_;

	switch( key )
	{
		case GLUT_KEY_PAGE_UP: 	_y_pos_ += 0.1f;	break;
		case GLUT_KEY_PAGE_DOWN:_y_pos_ -= 0.1f;	break;
		case GLUT_KEY_LEFT	:	Rotate += -0.05f;	break;		//	←
		case GLUT_KEY_UP	:	Zoom += +4;			break;		//	↑
		case GLUT_KEY_RIGHT	:	Rotate += +0.05f;	break;		//	→
		case GLUT_KEY_DOWN	:	Zoom += -4;			break;		//	↓
	}

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	gluLookAt( sin( Rotate ) * Zoom, _y_pos_, cos( Rotate ) * Zoom, 0, _y_pos_, 0, 0, 1, 0 );
}

void idle( void )
{
	//glutPostRedisplay();
}

void timer( int value )
{
	//glutTimerFunc( fps->get_wait_time() * 1000.0f, timer, 0 );
	glutTimerFunc( 1000.0f / fps->get_fps(), timer, 0 );
	fps->draw();
	fps->update();

	if( motion_flag )
	{
		float	frame = 30.0f / fps->get_mfps();	//fps->get_dframe();
		//	フレームを進める関数
		//（MMD は１秒間に３０フレームがデフォルト）
		//	60fpsで実行の場合、0.5frame ずつフレームにたいしてモーションを進める
		( *p->get_vmd( 0 ) ) += frame;
		//( *p->get_vmd( 0 ) ) ++;

		if( p->get_vmd( 0 )->is_end() )
			exit( 0 );
	}

	mmdpiMatrix	matrix;
	static float dy = 3.14f;
	//dy += 0.01f;
	//matrix.rotation( 0, 1, 0, dy );
	//matrix.rotation( 0, 1, 0, 3.14f );
	p->set_bone_matrix( 0, matrix );

	glutPostRedisplay();
}

void resize( int w, int h )
{
	glViewport( 0, 0, w, h );

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	//gluLookAt( 0.0f, _y_pos_, _zoom_default_, 0, _y_pos_, 0, 0, 1, 0 );
	gluLookAt( sin( Rotate ) * Zoom, _y_pos_, cos( Rotate ) * Zoom, 0, _y_pos_, 0, 0, 1, 0 );

	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	//	透視投影
	gluPerspective( 2.0f / 3, ( GLfloat )w / ( GLfloat )h, 1.0f, 65536.0f );
	//	正投影
	//glOrtho( -1.5, 1.5, -1.5, 1.5, -1.0, 1.0 );

	glMatrixMode( GL_MODELVIEW );

	screen_width = w;
	screen_height = h;
}

int		MousePushFlag = 0;
int		MousePosX = 0, MousePosY = 0;
void mouse_func( int button, int state, int x, int y )
{
	switch( button )
	{
	case GLUT_LEFT_BUTTON:
		{
			switch( state )
			{
			case GLUT_DOWN:
				{
					MousePushFlag = 1;
					MousePosX = x;
					MousePosY = y;
				} break;
			case GLUT_UP:
				{
					MousePushFlag = 0;
				} break;
			}
		} break;
	}
}

//	押してないとき
void mouse_passive_func( int x, int y )
{
}

//	押してるとき
void mouse_motion( int x, int y )
{
	if( MousePushFlag )
	{
		float	dy = ( float )( x - MousePosX ) / 4.0f;
		float	dx = ( float )( y - MousePosY ) / 4.0f;

		MousePosX = x;
		MousePosY = y;

		RotationAxis[ 0 ] -= dx;
		RotationAxis[ 1 ] += dy;
	}
}

void init( void )
{
	p = new mmdpi();
	if( p == NULL )
		exit( 0 );
	//p->set_physics_engine( 0 );

	// Test
	puts( Argv[ 1 ] );
	if( p->load( Argv[ 1 ] ) )
	//if( p->load( "udon/udon.pmx" ) )
	//if( p->load( "sakuya/sakuya.pmx" ) )
		exit( 0 );
	//p->load( "../Release/reimu/reimu.pmd"/*Argv[ 1 ]*/ );

	//	Sound
	if( Argc > 4 )
		system( ( const char* )Argv[ 4 ] );

	if( Argc > 2 )
	{
		motion_flag = 1;
		puts( Argv[ 2 ] );
		if( p->vmd_load( Argv[ 2 ] ) )
			motion_flag = 0;
	}
	//motion_flag = 1;
	//if( p->vmd_load( "vmd/nolifequeen.vmd" ) )
	//	motion_flag = 0;

	if( Argc > 3 )
	{
		_fps_ = atoi( Argv[ 3 ] );
		_fps_ = ( _fps_ < 6 || 480 < _fps_ )? 30.0f : _fps_ ;
	}
	fps = new Fps();
	fps->set_fps( _fps_ );

	p->set_fps( _fps_ );

	puts( "END Loading." );
}

void end( void )
{
	delete fps;
	delete p;
}

int main( int argc, char *argv[] )
{
	if( argc < 2 )
	{
		printf( "モデル、モーションを!\n\n" );
		return 0;
	}

	Zoom = _zoom_default_;
	Rotate = 0;

	Argc = argc;
	Argv = argv;

	glutInitWindowPosition( 200, 200 );
	glutInitWindowSize( 640, 480 );
	glutInit( &argc, argv );
	glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
	glutCreateWindow( argv[ 0 ] );

	glutDisplayFunc( display );
	glutReshapeFunc( resize );

	glutKeyboardFunc( keyboard );
	glutSpecialFunc( sp_keyboard );
	glutMouseFunc( mouse_func );
	glutPassiveMotionFunc( mouse_passive_func );
	glutMotionFunc( mouse_motion );

	init();

	//glutIdleFunc( idle );
	glutTimerFunc( 1000.0f / 30.0f , timer, 0 );

	glutMainLoop();

	end();

	return 0;
}
<commit_msg>Update gl_main.cpp<commit_after>

#include "../libmmdpi/mmdpi.h"
//#include "../gl_xfile/gl_xfile.h"

#ifdef _WIN32
#	ifdef _DEBUG
#		pragma comment( lib, "../Debug/libmmdpi.lib" )
#	else
#		pragma comment( lib, "../Release/libmmdpi.lib" )
#	endif
#endif

//#ifdef _DEBUG
//	#pragma comment( lib, "../Debug/gl_xfile.lib" )
//#else
//	#pragma comment( lib, "../Release/gl_xfile.lib" )
//#endif

#include <iostream>
#include "GL/glut.h"

const int		_zoom_default_	= -1024 * 2 * 0.1f;// * 16;
float			_y_pos_			= 11 * 0.1f;
static mmdpi*	p = NULL;
int				_fps_			= 30;
int 			motion_flag = 0;
float			Zoom;
float			Rotate;

float			RotationAxis[ 3 ];

int			screen_width, screen_height;

int			Argc;
char**			Argv;

#include "fps.h"

Fps* fps = NULL;

void end( void );

void display( void )
{
	GLfloat light0pos[] = { 4.0, 16.0, -8.0, 1.0 };

	glEnable( GL_DEPTH_TEST );

	glEnable( GL_LIGHTING );
	glEnable( GL_LIGHT0 );

	//glClearColor( 0.0, 0.0, 1.0, 1.0 );	//	bule
	//glClearColor( 0.0, 0.2, 0.0, 1.0 );	//	bule
	//glClearColor( 0.0, 0.0, 0.0, 1.0 );	//	black
	glClearColor( 1.0, 1.0, 1.0, 1.0 );	//	white
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	glColor3d( 1.0, 0.0, 0.0 );

	glLightfv( GL_LIGHT0, GL_POSITION, light0pos );

	float diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
	float ambient[] = { 1.0, 1.0, 1.0, 1.0 };
	glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse );
	glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient );

	static float rot = 0.0f;

	// カメラ
	glMatrixMode( GL_MODELVIEW );

	glPushMatrix();
	{
	//	glRotatef( rot, 1, 0, 0 );
		//glRotatef( 3.14f, 0, 1, 0 );
		//glRotatef( rot, 0, 1, 0 );
		//glTranslatef( 0, 0, Zoom );

		//glutSolidTeapot( 0.5 );

		glRotatef( RotationAxis[ 0 ], 1, 0, 0 );
		glRotatef( RotationAxis[ 1 ], 0, 1, 0 );

		glScalef( 0.1f, 0.1f, 0.1f );
		p->draw();
	}
	glPopMatrix();

	//rot += 0.1f;

	glutSwapBuffers();
}

void keyboard( unsigned char key, int x, int y )
{
	switch( key )
	{
	case 'q':
	case 'Q':
	case '\033':  /* '\033' は ESC の ASCII コード */
		end();
		exit( 0 );
	case 'u':
		//	fps
		if( fps->get_fps() < 120 )
		{
			fps->set_fps( fps->get_fps() + 5 );
			p->set_fps( fps->get_fps() );
		}
		break;
	case 'd':
		if( fps->get_fps() > 10 )
		{
			fps->set_fps( fps->get_fps() - 5 );
			p->set_fps( fps->get_fps() );
		}
		break;
	return ;

	default:
		break;
	}
}

void sp_keyboard( int key, int x, int y )
{
	//static float	rotate	= 0;
	//static float	zoom	= _zoom_default_;

	switch( key )
	{
		case GLUT_KEY_PAGE_UP: 	_y_pos_ += 0.1f;	break;
		case GLUT_KEY_PAGE_DOWN:_y_pos_ -= 0.1f;	break;
		case GLUT_KEY_LEFT	:	Rotate += -0.05f;	break;		//	←
		case GLUT_KEY_UP	:	Zoom += +4;			break;		//	↑
		case GLUT_KEY_RIGHT	:	Rotate += +0.05f;	break;		//	→
		case GLUT_KEY_DOWN	:	Zoom += -4;			break;		//	↓
	}

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	gluLookAt( sin( Rotate ) * Zoom, _y_pos_, cos( Rotate ) * Zoom, 0, _y_pos_, 0, 0, 1, 0 );
}

void idle( void )
{
	//glutPostRedisplay();
}

void timer( int value )
{
	//glutTimerFunc( fps->get_wait_time() * 1000.0f, timer, 0 );
	glutTimerFunc( 1000.0f / fps->get_fps(), timer, 0 );
	fps->draw();
	fps->update();

	if( motion_flag )
	{
		float	frame = 30.0f / fps->get_mfps();	//fps->get_dframe();
		//	フレームを進める関数
		//（MMD は１秒間に３０フレームがデフォルト）
		//	60fpsで実行の場合、0.5frame ずつフレームにたいしてモーションを進める
		( *p->get_vmd( 0 ) ) += frame;
		//( *p->get_vmd( 0 ) ) ++;

		if( p->get_vmd( 0 )->is_end() )
			exit( 0 );
	}

	mmdpiMatrix	matrix;
	static float dy = 3.14f;
	//dy += 0.01f;
	//matrix.rotation( 0, 1, 0, dy );
	//matrix.rotation( 0, 1, 0, 3.14f );
	p->set_bone_matrix( 0, matrix );

	glutPostRedisplay();
}

void resize( int w, int h )
{
	glViewport( 0, 0, w, h );

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	//gluLookAt( 0.0f, _y_pos_, _zoom_default_, 0, _y_pos_, 0, 0, 1, 0 );
	gluLookAt( sin( Rotate ) * Zoom, _y_pos_, cos( Rotate ) * Zoom, 0, _y_pos_, 0, 0, 1, 0 );

	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	//	透視投影
	gluPerspective( 2.0f / 3, ( GLfloat )w / ( GLfloat )h, 1.0f, 65536.0f );
	//	正投影
	//glOrtho( -1.5, 1.5, -1.5, 1.5, -1.0, 1.0 );

	glMatrixMode( GL_MODELVIEW );

	screen_width = w;
	screen_height = h;
}

int		MousePushFlag = 0;
int		MousePosX = 0, MousePosY = 0;
void mouse_func( int button, int state, int x, int y )
{
	switch( button )
	{
	case GLUT_LEFT_BUTTON:
		{
			switch( state )
			{
			case GLUT_DOWN:
				{
					MousePushFlag = 1;
					MousePosX = x;
					MousePosY = y;
				} break;
			case GLUT_UP:
				{
					MousePushFlag = 0;
				} break;
			}
		} break;
	}
}

//	押してないとき
void mouse_passive_func( int x, int y )
{
}

//	押してるとき
void mouse_motion( int x, int y )
{
	if( MousePushFlag )
	{
		float	dy = ( float )( x - MousePosX ) / 4.0f;
		float	dx = ( float )( y - MousePosY ) / 4.0f;

		MousePosX = x;
		MousePosY = y;

		RotationAxis[ 0 ] -= dx;
		RotationAxis[ 1 ] += dy;
	}
}

void init( void )
{
	p = new mmdpi();
	if( p == NULL )
		exit( 0 );
	//p->set_physics_engine( 0 );

	// Test
	puts( Argv[ 1 ] );
	if( p->load( Argv[ 1 ] ) )
	//if( p->load( "udon/udon.pmx" ) )
	//if( p->load( "sakuya/sakuya.pmx" ) )
		exit( 0 );
	//p->load( "../Release/reimu/reimu.pmd"/*Argv[ 1 ]*/ );

	////	Sound
	//if( Argc > 4 )
	//	system( ( const char* )Argv[ 4 ] );

	if( Argc > 2 )
	{
		motion_flag = 1;
		puts( Argv[ 2 ] );
		if( p->vmd_load( Argv[ 2 ] ) )
			motion_flag = 0;
	}
	//motion_flag = 1;
	//if( p->vmd_load( "vmd/nolifequeen.vmd" ) )
	//	motion_flag = 0;

	if( Argc > 3 )
	{
		_fps_ = atoi( Argv[ 3 ] );
		_fps_ = ( _fps_ < 6 || 480 < _fps_ )? 30.0f : _fps_ ;
	}
	fps = new Fps();
	fps->set_fps( _fps_ );

	p->set_fps( _fps_ );

	puts( "END Loading." );
}

void end( void )
{
	delete fps;
	delete p;
}

int main( int argc, char *argv[] )
{
	if( argc < 2 )
	{
		printf( "モデル、モーションを!\n\n" );
		return 0;
	}

	Zoom = _zoom_default_;
	Rotate = 0;

	Argc = argc;
	Argv = argv;

	glutInitWindowPosition( 200, 200 );
	glutInitWindowSize( 640, 480 );
	glutInit( &argc, argv );
	glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
	glutCreateWindow( argv[ 0 ] );

	glutDisplayFunc( display );
	glutReshapeFunc( resize );

	glutKeyboardFunc( keyboard );
	glutSpecialFunc( sp_keyboard );
	glutMouseFunc( mouse_func );
	glutPassiveMotionFunc( mouse_passive_func );
	glutMotionFunc( mouse_motion );

	init();

	//glutIdleFunc( idle );
	glutTimerFunc( 1000.0f / 30.0f , timer, 0 );

	glutMainLoop();

	end();

	return 0;
}
<|endoftext|>


<commit_before><commit_msg>Significantly increase timeouts to reduce flakiness<commit_after><|endoftext|>