<commit_before>#pragma once
#include "macros.h"
#include <openrave/openrave.h>
#include <map>
#include <boost/make_shared.hpp>
#include "utils/logging.hpp"
#include <iostream>

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

namespace trajopt {

#if OPENRAVE_VERSION_MINOR > 8

#define TRAJOPT_DATA ("__trajopt_data__")

inline OpenRAVE::UserDataPtr GetUserData(const OpenRAVE::InterfaceBase& body, const std::string& key) {
  OpenRAVE::UserDataPtr val = body.GetUserData(key);
  std::cout << ">>>> GET " << key << ": " << val << std::endl;
  return val;
}
inline void SetUserData(OpenRAVE::InterfaceBase& body, const std::string& key, OpenRAVE::UserDataPtr val) {
  std::cout << ">>>> SET " << key << ": " << val << std::endl;
  body.SetUserData(key, val);
}
inline void RemoveUserData(OpenRAVE::InterfaceBase& body, const std::string& key) {
  std::cout << ">>>> REM " << key << std::endl;
  body.RemoveUserData(key);
}

inline OpenRAVE::KinBodyPtr GetEnvDataObject(OpenRAVE::EnvironmentBase& env) {
  OpenRAVE::KinBodyPtr trajopt_data = env.GetKinBody("__trajopt_data__");
  if (!trajopt_data) {
    OpenRAVE::Vector v;
    std::vector< OpenRAVE::Vector > svec;
    svec.push_back(v);
    trajopt_data = OpenRAVE::RaveCreateKinBody(env.shared_from_this(), "");
    trajopt_data->SetName("__trajopt_data__");
    trajopt_data->InitFromSpheres(svec, false);
    env.Add(trajopt_data);
  }
  return trajopt_data;
}

inline OpenRAVE::UserDataPtr GetUserData(OpenRAVE::EnvironmentBase& env, const std::string& key) {
  return GetEnvDataObject(env)->GetUserData(key);
}
inline void SetUserData(OpenRAVE::EnvironmentBase& env, const std::string& key, OpenRAVE::UserDataPtr val) {
  GetEnvDataObject(env)->SetUserData(key, val);
}
inline void RemoveUserData(OpenRAVE::EnvironmentBase& env, const std::string& key) {
  GetEnvDataObject(env)->RemoveUserData(key);
}

#else // OPENRAVE_VERSION_MINOR > 8

class UserMap : public std::map<std::string, OpenRAVE::UserDataPtr>, public OpenRAVE::UserData {};

template <typename T>
OpenRAVE::UserDataPtr GetUserData(const T& env, const std::string& key) {
  OpenRAVE::UserDataPtr ud = env.GetUserData();
  if (!ud) return OpenRAVE::UserDataPtr();
  else if (UserMap* um = dynamic_cast<UserMap*>(ud.get())) {
    UserMap::iterator it = (*um).find(key);
    if (it != (*um).end()) return it->second;
    else return OpenRAVE::UserDataPtr();
  }
  else {
    throw OpenRAVE::openrave_exception("Userdata has the wrong class!");
    return OpenRAVE::UserDataPtr();
  }
}
template <typename T>
void SetUserData(T& env, const std::string& key, OpenRAVE::UserDataPtr val) {
  OpenRAVE::UserDataPtr ud = env.GetUserData();
  if (!ud) {
    ud = OpenRAVE::UserDataPtr(new UserMap());
    env.SetUserData(ud);
  }
  if (UserMap* um = dynamic_cast<UserMap*>(ud.get())) {
    (*um)[key] = val;
  }
  else {
    throw OpenRAVE::openrave_exception("userdata has unexpected class");
  }
}
template <typename T>
void RemoveUserData(T& body, const std::string& key) {
  OpenRAVE::UserDataPtr ud = body.GetUserData();
  if (UserMap* um = dynamic_cast<UserMap*>(ud.get())) {
    if (um->find(key) == um->end()) LOG_WARN("tried to erase key %s but it's not in the userdata map!", key.c_str());
    (*um).erase(key);
  }
  else {
    LOG_ERROR("body %s has no userdata map", body.GetName().c_str());
  }
}

#endif // OPENRAVE_VERSION_MINOR > 8

}
<commit_msg>Removed key-value store debugging information.<commit_after>#pragma once
#include "macros.h"
#include <openrave/openrave.h>
#include <map>
#include <boost/make_shared.hpp>
#include "utils/logging.hpp"
#include <iostream>

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

namespace trajopt {

#if OPENRAVE_VERSION_MINOR > 8

#define TRAJOPT_DATA ("__trajopt_data__")

inline OpenRAVE::UserDataPtr GetUserData(const OpenRAVE::InterfaceBase& body, const std::string& key) {
  return body.GetUserData(key);
}
inline void SetUserData(OpenRAVE::InterfaceBase& body, const std::string& key, OpenRAVE::UserDataPtr val) {
  body.SetUserData(key, val);
}
inline void RemoveUserData(OpenRAVE::InterfaceBase& body, const std::string& key) {
  body.RemoveUserData(key);
}

inline OpenRAVE::KinBodyPtr GetEnvDataObject(OpenRAVE::EnvironmentBase& env) {
  OpenRAVE::KinBodyPtr trajopt_data = env.GetKinBody("__trajopt_data__");
  if (!trajopt_data) {
    std::vector< OpenRAVE::Vector > svec;
    trajopt_data = OpenRAVE::RaveCreateKinBody(env.shared_from_this(), "");
    trajopt_data->SetName("__trajopt_data__");
    trajopt_data->InitFromSpheres(svec, false);
    env.Add(trajopt_data);
  }
  return trajopt_data;
}

inline OpenRAVE::UserDataPtr GetUserData(OpenRAVE::EnvironmentBase& env, const std::string& key) {
  return GetEnvDataObject(env)->GetUserData(key);
}
inline void SetUserData(OpenRAVE::EnvironmentBase& env, const std::string& key, OpenRAVE::UserDataPtr val) {
  GetEnvDataObject(env)->SetUserData(key, val);
}
inline void RemoveUserData(OpenRAVE::EnvironmentBase& env, const std::string& key) {
  GetEnvDataObject(env)->RemoveUserData(key);
}

#else // OPENRAVE_VERSION_MINOR > 8

class UserMap : public std::map<std::string, OpenRAVE::UserDataPtr>, public OpenRAVE::UserData {};

template <typename T>
OpenRAVE::UserDataPtr GetUserData(const T& env, const std::string& key) {
  OpenRAVE::UserDataPtr ud = env.GetUserData();
  if (!ud) return OpenRAVE::UserDataPtr();
  else if (UserMap* um = dynamic_cast<UserMap*>(ud.get())) {
    UserMap::iterator it = (*um).find(key);
    if (it != (*um).end()) return it->second;
    else return OpenRAVE::UserDataPtr();
  }
  else {
    throw OpenRAVE::openrave_exception("Userdata has the wrong class!");
    return OpenRAVE::UserDataPtr();
  }
}
template <typename T>
void SetUserData(T& env, const std::string& key, OpenRAVE::UserDataPtr val) {
  OpenRAVE::UserDataPtr ud = env.GetUserData();
  if (!ud) {
    ud = OpenRAVE::UserDataPtr(new UserMap());
    env.SetUserData(ud);
  }
  if (UserMap* um = dynamic_cast<UserMap*>(ud.get())) {
    (*um)[key] = val;
  }
  else {
    throw OpenRAVE::openrave_exception("userdata has unexpected class");
  }
}
template <typename T>
void RemoveUserData(T& body, const std::string& key) {
  OpenRAVE::UserDataPtr ud = body.GetUserData();
  if (UserMap* um = dynamic_cast<UserMap*>(ud.get())) {
    if (um->find(key) == um->end()) LOG_WARN("tried to erase key %s but it's not in the userdata map!", key.c_str());
    (*um).erase(key);
  }
  else {
    LOG_ERROR("body %s has no userdata map", body.GetName().c_str());
  }
}

#endif // OPENRAVE_VERSION_MINOR > 8

}
<|endoftext|>


<commit_before>/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

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

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

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

#ifdef __GNUC__
#pragma implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
#include <myisampack.h>
#include "ha_heap.h"

/*****************************************************************************
** HEAP tables
*****************************************************************************/

const char **ha_heap::bas_ext() const
{ static const char *ext[1]= { NullS }; return ext; }

int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
  uint key,parts,mem_per_row=0;
  ulong max_rows;
  HP_KEYDEF *keydef;
  HP_KEYSEG *seg;
  THD *thd= current_thd;

  for (key=parts=0 ; key < table->keys ; key++)
    parts+=table->key_info[key].key_parts;

  if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+
				      parts*sizeof(HP_KEYSEG),MYF(MY_WME))))
    return my_errno;
  seg=my_reinterpret_cast(HP_KEYSEG*) (keydef+table->keys);
  for (key=0 ; key < table->keys ; key++)
  {
    KEY *pos=table->key_info+key;
    KEY_PART_INFO *key_part=     pos->key_part;
    KEY_PART_INFO *key_part_end= key_part+pos->key_parts;

    mem_per_row += (pos->key_length + (sizeof(char*) * 2));

    keydef[key].keysegs=(uint) pos->key_parts;
    keydef[key].flag = (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
    keydef[key].seg=seg;

    for (; key_part != key_part_end ; key_part++, seg++)
    {
      uint flag=key_part->key_type;
      Field *field=key_part->field;
      if (!f_is_packed(flag) &&
	  f_packtype(flag) == (int) FIELD_TYPE_DECIMAL &&
	  !(flag & FIELDFLAG_BINARY))
	seg->type= (int) HA_KEYTYPE_TEXT;
      else
	seg->type= (int) HA_KEYTYPE_BINARY;
      seg->start=(uint) key_part->offset;
      seg->length=(uint) key_part->length;
      if (field->null_ptr)
      {
	seg->null_bit=field->null_bit;
	seg->null_pos= (uint) (field->null_ptr-
			       (uchar*) table->record[0]);
      }
      else
      {
	seg->null_bit=0;
	seg->null_pos=0;
      }
    }
  }
  mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*));
  max_rows = (ulong) (thd->variables.max_heap_table_size / mem_per_row);
  file=heap_open(name,mode,
		 table->keys,keydef,
		 table->reclength,
		 (ulong) ((table->max_rows < max_rows && table->max_rows) ?
			  table->max_rows : max_rows),
		 (ulong) table->min_rows);
  my_free((gptr) keydef,MYF(0));
  if (file)
    info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
  ref_length=sizeof(HEAP_PTR);
  return (!file ? errno : 0);
}

int ha_heap::close(void)
{
  return heap_close(file);
}

int ha_heap::write_row(byte * buf)
{
  statistic_increment(ha_write_count,&LOCK_status);
  if (table->time_stamp)
    update_timestamp(buf+table->time_stamp-1);
  return heap_write(file,buf);
}

int ha_heap::update_row(const byte * old_data, byte * new_data)
{
  statistic_increment(ha_update_count,&LOCK_status);
  if (table->time_stamp)
    update_timestamp(new_data+table->time_stamp-1);
  return heap_update(file,old_data,new_data);
}

int ha_heap::delete_row(const byte * buf)
{
  statistic_increment(ha_delete_count,&LOCK_status);
  return heap_delete(file,buf);
}

int ha_heap::index_read(byte * buf, const byte * key,
			uint key_len __attribute__((unused)),
			enum ha_rkey_function find_flag
			__attribute__((unused)))
{
  statistic_increment(ha_read_key_count,&LOCK_status);
  int error=heap_rkey(file,buf,active_index, key);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
			    uint key_len __attribute__((unused)),
			    enum ha_rkey_function find_flag
			    __attribute__((unused)))
{
  statistic_increment(ha_read_key_count,&LOCK_status);
  int error=heap_rkey(file, buf, index, key);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_next(byte * buf)
{
  statistic_increment(ha_read_next_count,&LOCK_status);
  int error=heap_rnext(file,buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_prev(byte * buf)
{
  statistic_increment(ha_read_prev_count,&LOCK_status);
  int error=heap_rprev(file,buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_first(byte * buf)
{
  statistic_increment(ha_read_first_count,&LOCK_status);
  int error=heap_rfirst(file, buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_last(byte * buf)
{
  statistic_increment(ha_read_last_count,&LOCK_status);
  int error=heap_rlast(file, buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::rnd_init(bool scan)
{
  return scan ? heap_scan_init(file) : 0;
}

int ha_heap::rnd_next(byte *buf)
{
  statistic_increment(ha_read_rnd_next_count,&LOCK_status);
  int error=heap_scan(file, buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::rnd_pos(byte * buf, byte *pos)
{
  int error;
  HEAP_PTR position;
  statistic_increment(ha_read_rnd_count,&LOCK_status);
  memcpy_fixed((char*) &position,pos,sizeof(HEAP_PTR));
  error=heap_rrnd(file, buf, position);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

void ha_heap::position(const byte *record)
{
  *(HEAP_PTR*) ref= heap_position(file);	// Ref is aligned
}

void ha_heap::info(uint flag)
{
  HEAPINFO info;
  (void) heap_info(file,&info,flag);

  records = info.records;
  deleted = info.deleted;
  errkey  = info.errkey;
  mean_rec_length=info.reclength;
  data_file_length=info.data_length;
  index_file_length=info.index_length;
  max_data_file_length= info.max_records* info.reclength;
  delete_length= info.deleted * info.reclength;
  implicit_emptied= info.implicit_emptied;
}

int ha_heap::extra(enum ha_extra_function operation)
{
  return heap_extra(file,operation);
}

int ha_heap::reset(void)
{
  return heap_extra(file,HA_EXTRA_RESET);
}

int ha_heap::delete_all_rows()
{
  heap_clear(file);
  return 0;
}

int ha_heap::external_lock(THD *thd, int lock_type)
{
  return 0;					// No external locking
}

THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
				    THR_LOCK_DATA **to,
				    enum thr_lock_type lock_type)
{
  if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
    file->lock.type=lock_type;
  *to++= &file->lock;
  return to;
}

/*
  We have to ignore ENOENT entries as the HEAP table is created on open and
  not when doing a CREATE on the table.
*/

int ha_heap::delete_table(const char *name)
{
  int error=heap_delete_table(name);
  return error == ENOENT ? 0 : error;
}

int ha_heap::rename_table(const char * from, const char * to)
{
  return heap_rename(from,to);
}

ha_rows ha_heap::records_in_range(int inx,
				  const byte *start_key,uint start_key_len,
				  enum ha_rkey_function start_search_flag,
				  const byte *end_key,uint end_key_len,
				  enum ha_rkey_function end_search_flag)
{
  KEY *pos=table->key_info+inx;
  if (start_key_len != end_key_len ||
      start_key_len != pos->key_length ||
      start_search_flag != HA_READ_KEY_EXACT ||
      end_search_flag != HA_READ_AFTER_KEY)
    return HA_POS_ERROR;			// Can't only use exact keys
  return 10;					// Good guess
}

int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)

{
  char buff[FN_REFLEN];
  return heap_create(fn_format(buff,name,"","",4+2));
}
<commit_msg>fixed Bug #4973 Memory is not released when HEAP table is dropped<commit_after>/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

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

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

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

#ifdef __GNUC__
#pragma implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
#include <myisampack.h>
#include "ha_heap.h"

/*****************************************************************************
** HEAP tables
*****************************************************************************/

const char **ha_heap::bas_ext() const
{ static const char *ext[1]= { NullS }; return ext; }

int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
  uint key,parts,mem_per_row=0;
  ulong max_rows;
  HP_KEYDEF *keydef;
  HP_KEYSEG *seg;
  THD *thd= current_thd;

  for (key=parts=0 ; key < table->keys ; key++)
    parts+=table->key_info[key].key_parts;

  if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+
				      parts*sizeof(HP_KEYSEG),MYF(MY_WME))))
    return my_errno;
  seg=my_reinterpret_cast(HP_KEYSEG*) (keydef+table->keys);
  for (key=0 ; key < table->keys ; key++)
  {
    KEY *pos=table->key_info+key;
    KEY_PART_INFO *key_part=     pos->key_part;
    KEY_PART_INFO *key_part_end= key_part+pos->key_parts;

    mem_per_row += (pos->key_length + (sizeof(char*) * 2));

    keydef[key].keysegs=(uint) pos->key_parts;
    keydef[key].flag = (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
    keydef[key].seg=seg;

    for (; key_part != key_part_end ; key_part++, seg++)
    {
      uint flag=key_part->key_type;
      Field *field=key_part->field;
      if (!f_is_packed(flag) &&
	  f_packtype(flag) == (int) FIELD_TYPE_DECIMAL &&
	  !(flag & FIELDFLAG_BINARY))
	seg->type= (int) HA_KEYTYPE_TEXT;
      else
	seg->type= (int) HA_KEYTYPE_BINARY;
      seg->start=(uint) key_part->offset;
      seg->length=(uint) key_part->length;
      if (field->null_ptr)
      {
	seg->null_bit=field->null_bit;
	seg->null_pos= (uint) (field->null_ptr-
			       (uchar*) table->record[0]);
      }
      else
      {
	seg->null_bit=0;
	seg->null_pos=0;
      }
    }
  }
  mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*));
  max_rows = (ulong) (thd->variables.max_heap_table_size / mem_per_row);
  file=heap_open(name,mode,
		 table->keys,keydef,
		 table->reclength,
		 (ulong) ((table->max_rows < max_rows && table->max_rows) ?
			  table->max_rows : max_rows),
		 (ulong) table->min_rows);
  my_free((gptr) keydef,MYF(0));
  if (file)
    info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
  ref_length=sizeof(HEAP_PTR);
  return (!file ? errno : 0);
}

int ha_heap::close(void)
{
  return heap_close(file);
}

int ha_heap::write_row(byte * buf)
{
  statistic_increment(ha_write_count,&LOCK_status);
  if (table->time_stamp)
    update_timestamp(buf+table->time_stamp-1);
  return heap_write(file,buf);
}

int ha_heap::update_row(const byte * old_data, byte * new_data)
{
  statistic_increment(ha_update_count,&LOCK_status);
  if (table->time_stamp)
    update_timestamp(new_data+table->time_stamp-1);
  return heap_update(file,old_data,new_data);
}

int ha_heap::delete_row(const byte * buf)
{
  statistic_increment(ha_delete_count,&LOCK_status);
  return heap_delete(file,buf);
}

int ha_heap::index_read(byte * buf, const byte * key,
			uint key_len __attribute__((unused)),
			enum ha_rkey_function find_flag
			__attribute__((unused)))
{
  statistic_increment(ha_read_key_count,&LOCK_status);
  int error=heap_rkey(file,buf,active_index, key);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
			    uint key_len __attribute__((unused)),
			    enum ha_rkey_function find_flag
			    __attribute__((unused)))
{
  statistic_increment(ha_read_key_count,&LOCK_status);
  int error=heap_rkey(file, buf, index, key);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_next(byte * buf)
{
  statistic_increment(ha_read_next_count,&LOCK_status);
  int error=heap_rnext(file,buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_prev(byte * buf)
{
  statistic_increment(ha_read_prev_count,&LOCK_status);
  int error=heap_rprev(file,buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_first(byte * buf)
{
  statistic_increment(ha_read_first_count,&LOCK_status);
  int error=heap_rfirst(file, buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::index_last(byte * buf)
{
  statistic_increment(ha_read_last_count,&LOCK_status);
  int error=heap_rlast(file, buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::rnd_init(bool scan)
{
  return scan ? heap_scan_init(file) : 0;
}

int ha_heap::rnd_next(byte *buf)
{
  statistic_increment(ha_read_rnd_next_count,&LOCK_status);
  int error=heap_scan(file, buf);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

int ha_heap::rnd_pos(byte * buf, byte *pos)
{
  int error;
  HEAP_PTR position;
  statistic_increment(ha_read_rnd_count,&LOCK_status);
  memcpy_fixed((char*) &position,pos,sizeof(HEAP_PTR));
  error=heap_rrnd(file, buf, position);
  table->status=error ? STATUS_NOT_FOUND: 0;
  return error;
}

void ha_heap::position(const byte *record)
{
  *(HEAP_PTR*) ref= heap_position(file);	// Ref is aligned
}

void ha_heap::info(uint flag)
{
  HEAPINFO info;
  (void) heap_info(file,&info,flag);

  records = info.records;
  deleted = info.deleted;
  errkey  = info.errkey;
  mean_rec_length=info.reclength;
  data_file_length=info.data_length;
  index_file_length=info.index_length;
  max_data_file_length= info.max_records* info.reclength;
  delete_length= info.deleted * info.reclength;
  implicit_emptied= info.implicit_emptied;
}

int ha_heap::extra(enum ha_extra_function operation)
{
  return heap_extra(file,operation);
}

int ha_heap::reset(void)
{
  return heap_extra(file,HA_EXTRA_RESET);
}

int ha_heap::delete_all_rows()
{
  heap_clear(file);
  return 0;
}

int ha_heap::external_lock(THD *thd, int lock_type)
{
  return 0;					// No external locking
}

THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
				    THR_LOCK_DATA **to,
				    enum thr_lock_type lock_type)
{
  if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
    file->lock.type=lock_type;
  *to++= &file->lock;
  return to;
}

/*
  We have to ignore ENOENT entries as the HEAP table is created on open and
  not when doing a CREATE on the table.
*/

int ha_heap::delete_table(const char *name)
{
  char buff[FN_REFLEN];
  int error= heap_delete_table(fn_format(buff,name,"","",4+2));
  return error == ENOENT ? 0 : error;
}

int ha_heap::rename_table(const char * from, const char * to)
{
  return heap_rename(from,to);
}

ha_rows ha_heap::records_in_range(int inx,
				  const byte *start_key,uint start_key_len,
				  enum ha_rkey_function start_search_flag,
				  const byte *end_key,uint end_key_len,
				  enum ha_rkey_function end_search_flag)
{
  KEY *pos=table->key_info+inx;
  if (start_key_len != end_key_len ||
      start_key_len != pos->key_length ||
      start_search_flag != HA_READ_KEY_EXACT ||
      end_search_flag != HA_READ_AFTER_KEY)
    return HA_POS_ERROR;			// Can't only use exact keys
  return 10;					// Good guess
}

int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)

{
  char buff[FN_REFLEN];
  return heap_create(fn_format(buff,name,"","",4+2));
}
<|endoftext|>


<commit_before>//===-- examples/clang-interpreter/main.cpp - Clang C Interpreter Example -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/CodeGen/CodeGenAction.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Config/config.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
#include "llvm/Target/TargetSelect.h"
using namespace clang;
using namespace clang::driver;

llvm::sys::Path GetExecutablePath(const char *Argv0) {
  // This just needs to be some symbol in the binary; C++ doesn't
  // allow taking the address of ::main however.
  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
  return llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
}

int Execute(llvm::Module *Mod, char * const *envp) {
  llvm::InitializeNativeTarget();

  std::string Error;
  llvm::OwningPtr<llvm::ExecutionEngine> EE(
    llvm::ExecutionEngine::createJIT(Mod, &Error));
  if (!EE) {
    llvm::errs() << "unable to make execution engine: " << Error << "\n";
    return 255;
  }

  llvm::Function *EntryFn = Mod->getFunction("main");
  if (!EntryFn) {
    llvm::errs() << "'main' function not found in module.\n";
    return 255;
  }

  // FIXME: Support passing arguments.
  std::vector<std::string> Args;
  Args.push_back(Mod->getModuleIdentifier());

  return EE->runFunctionAsMain(EntryFn, Args, envp);
}

int main(int argc, const char **argv, char * const *envp) {
  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
  llvm::sys::Path Path = GetExecutablePath(argv[0]);
  TextDiagnosticPrinter *DiagClient =
    new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());

  Diagnostic Diags(DiagClient);
  Driver TheDriver(Path.str(), llvm::sys::getHostTriple(),
                   "a.out", /*IsProduction=*/false, /*CXXIsProduction=*/false,
                   Diags);
  TheDriver.setTitle("clang interpreter");

  // FIXME: This is a hack to try to force the driver to do something we can
  // recognize. We need to extend the driver library to support this use model
  // (basically, exactly one input, and the operation mode is hard wired).
  llvm::SmallVector<const char *, 16> Args(argv, argv + argc);
  Args.push_back("-fsyntax-only");
  llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args.size(),
                                                            Args.data()));
  if (!C)
    return 0;

  // FIXME: This is copied from ASTUnit.cpp; simplify and eliminate.

  // We expect to get back exactly one command job, if we didn't something
  // failed. Extract that job from the compilation.
  const driver::JobList &Jobs = C->getJobs();
  if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
    llvm::SmallString<256> Msg;
    llvm::raw_svector_ostream OS(Msg);
    C->PrintJob(OS, C->getJobs(), "; ", true);
    Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
    return 1;
  }

  const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
  if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
    Diags.Report(diag::err_fe_expected_clang_command);
    return 1;
  }

  // Initialize a compiler invocation object from the clang (-cc1) arguments.
  const driver::ArgStringList &CCArgs = Cmd->getArguments();
  llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
  CompilerInvocation::CreateFromArgs(*CI,
                                     const_cast<const char **>(CCArgs.data()),
                                     const_cast<const char **>(CCArgs.data()) +
                                       CCArgs.size(),
                                     Diags);

  // Show the invocation, with -v.
  if (CI->getHeaderSearchOpts().Verbose) {
    llvm::errs() << "clang invocation:\n";
    C->PrintJob(llvm::errs(), C->getJobs(), "\n", true);
    llvm::errs() << "\n";
  }

  // FIXME: This is copied from cc1_main.cpp; simplify and eliminate.

  // Create a compiler instance to handle the actual work.
  CompilerInstance Clang;
  Clang.setLLVMContext(new llvm::LLVMContext);
  Clang.setInvocation(CI.take());

  // Create the compilers actual diagnostics engine.
  Clang.createDiagnostics(int(CCArgs.size()),const_cast<char**>(CCArgs.data()));
  if (!Clang.hasDiagnostics())
    return 1;

  // Infer the builtin include path if unspecified.
  if (Clang.getHeaderSearchOpts().UseBuiltinIncludes &&
      Clang.getHeaderSearchOpts().ResourceDir.empty())
    Clang.getHeaderSearchOpts().ResourceDir =
      CompilerInvocation::GetResourcesPath(argv[0], MainAddr);

  // Create and execute the frontend to generate an LLVM bitcode module.
  llvm::OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction());
  if (!Clang.ExecuteAction(*Act))
    return 1;

  int Res = 255;
  if (llvm::Module *Module = Act->takeModule())
    Res = Execute(Module, envp);

  // Shutdown.

  llvm::llvm_shutdown();

  return Res;
}
<commit_msg>These functions don't need external linkage.<commit_after>//===-- examples/clang-interpreter/main.cpp - Clang C Interpreter Example -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/CodeGen/CodeGenAction.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Config/config.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
#include "llvm/Target/TargetSelect.h"
using namespace clang;
using namespace clang::driver;

static llvm::sys::Path GetExecutablePath(const char *Argv0) {
  // This just needs to be some symbol in the binary; C++ doesn't
  // allow taking the address of ::main however.
  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
  return llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
}

static int Execute(llvm::Module *Mod, char * const *envp) {
  llvm::InitializeNativeTarget();

  std::string Error;
  llvm::OwningPtr<llvm::ExecutionEngine> EE(
    llvm::ExecutionEngine::createJIT(Mod, &Error));
  if (!EE) {
    llvm::errs() << "unable to make execution engine: " << Error << "\n";
    return 255;
  }

  llvm::Function *EntryFn = Mod->getFunction("main");
  if (!EntryFn) {
    llvm::errs() << "'main' function not found in module.\n";
    return 255;
  }

  // FIXME: Support passing arguments.
  std::vector<std::string> Args;
  Args.push_back(Mod->getModuleIdentifier());

  return EE->runFunctionAsMain(EntryFn, Args, envp);
}

int main(int argc, const char **argv, char * const *envp) {
  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
  llvm::sys::Path Path = GetExecutablePath(argv[0]);
  TextDiagnosticPrinter *DiagClient =
    new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());

  Diagnostic Diags(DiagClient);
  Driver TheDriver(Path.str(), llvm::sys::getHostTriple(),
                   "a.out", /*IsProduction=*/false, /*CXXIsProduction=*/false,
                   Diags);
  TheDriver.setTitle("clang interpreter");

  // FIXME: This is a hack to try to force the driver to do something we can
  // recognize. We need to extend the driver library to support this use model
  // (basically, exactly one input, and the operation mode is hard wired).
  llvm::SmallVector<const char *, 16> Args(argv, argv + argc);
  Args.push_back("-fsyntax-only");
  llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args.size(),
                                                            Args.data()));
  if (!C)
    return 0;

  // FIXME: This is copied from ASTUnit.cpp; simplify and eliminate.

  // We expect to get back exactly one command job, if we didn't something
  // failed. Extract that job from the compilation.
  const driver::JobList &Jobs = C->getJobs();
  if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
    llvm::SmallString<256> Msg;
    llvm::raw_svector_ostream OS(Msg);
    C->PrintJob(OS, C->getJobs(), "; ", true);
    Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
    return 1;
  }

  const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
  if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
    Diags.Report(diag::err_fe_expected_clang_command);
    return 1;
  }

  // Initialize a compiler invocation object from the clang (-cc1) arguments.
  const driver::ArgStringList &CCArgs = Cmd->getArguments();
  llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
  CompilerInvocation::CreateFromArgs(*CI,
                                     const_cast<const char **>(CCArgs.data()),
                                     const_cast<const char **>(CCArgs.data()) +
                                       CCArgs.size(),
                                     Diags);

  // Show the invocation, with -v.
  if (CI->getHeaderSearchOpts().Verbose) {
    llvm::errs() << "clang invocation:\n";
    C->PrintJob(llvm::errs(), C->getJobs(), "\n", true);
    llvm::errs() << "\n";
  }

  // FIXME: This is copied from cc1_main.cpp; simplify and eliminate.

  // Create a compiler instance to handle the actual work.
  CompilerInstance Clang;
  Clang.setLLVMContext(new llvm::LLVMContext);
  Clang.setInvocation(CI.take());

  // Create the compilers actual diagnostics engine.
  Clang.createDiagnostics(int(CCArgs.size()),const_cast<char**>(CCArgs.data()));
  if (!Clang.hasDiagnostics())
    return 1;

  // Infer the builtin include path if unspecified.
  if (Clang.getHeaderSearchOpts().UseBuiltinIncludes &&
      Clang.getHeaderSearchOpts().ResourceDir.empty())
    Clang.getHeaderSearchOpts().ResourceDir =
      CompilerInvocation::GetResourcesPath(argv[0], MainAddr);

  // Create and execute the frontend to generate an LLVM bitcode module.
  llvm::OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction());
  if (!Clang.ExecuteAction(*Act))
    return 1;

  int Res = 255;
  if (llvm::Module *Module = Act->takeModule())
    Res = Execute(Module, envp);

  // Shutdown.

  llvm::llvm_shutdown();

  return Res;
}
<|endoftext|>


<commit_before><commit_msg>coverity#1242717 Untrusted loop bound<commit_after><|endoftext|>


<commit_before>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"
#include "raw.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(char *input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  size_t input_size = strlen(input);
  for (size_t i = 0; i < input_size; i++) {
    if (input[i] != delimiter) {
      word += input[i];
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

void StripChar(char *input, char c) {
  size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
    if (input[i] == c) {
      input[i] = '\0';
    }
  }
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    cooked_mode();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "\n*Unknown command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
  char *input;
  char tmp_buffer[SAY_MAX];
  memset(&tmp_buffer, 0, SAY_MAX);

  char stdin_buffer[SAY_MAX + 1];
  char *stdin_buffer_position = stdin_buffer;

//  struct timeval timeout;
  fd_set read_set;
//  int file_desc = 0;
  int result;
  char receive_buffer[kBufferSize];
  memset(&receive_buffer, 0, kBufferSize);

//  char stdin_buffer[kBufferSize];
//  memset(&stdin_buffer, 0, kBufferSize);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  if (raw_mode() != 0){
    Error("client: error using raw mode");
  }

  std::cout << ">" << std::flush;

  bool is_newline = false;

  while (1) {
    FD_ZERO(&read_set);
    FD_SET(client_socket, &read_set);
    FD_SET(STDIN_FILENO, &read_set);

    if ((result = select(client_socket + 1, &read_set, NULL, NULL, NULL)) < 0) {
      Error("client: problem using select");
    }

    if (result > 0) {
      if (FD_ISSET(STDIN_FILENO, &read_set)) {
        char c = (char) getchar();
        if (c == '\n') {
          *stdin_buffer_position++ = '\0';
          stdin_buffer_position = stdin_buffer;
          printf("\n");
          fflush(stdout);
          input = stdin_buffer;
          is_newline = true;

          if (input[0] == '/') {
            if (!ProcessInput(input)) {
              break;
            }
          } else {
            // Send chat messages
            RequestSay(input);
          }
        } else if (stdin_buffer_position != stdin_buffer + SAY_MAX) {
          is_newline = false;
          *stdin_buffer_position++ = c;
          printf("%c", c);
//          std::cout << c << std::endl;
          fflush(stdout);
        }
      } else if (FD_ISSET(client_socket, &read_set)) {
        // Socket has data
        int read_size = read(client_socket, receive_buffer, kBufferSize);

        if (read_size != 0) {
          // TODO capture user input, store, clean input, then print buffer, afterward replace input
          struct text message;
          memcpy(&message, receive_buffer, sizeof(struct text));
          text_t text_type = message.txt_type;

          switch (text_type) {
            case TXT_SAY:
              struct text_say say;
              memcpy(&say, receive_buffer, sizeof(struct text_say));
              std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
              std::cout << "[" << say.txt_channel << "]" << "[" << say.txt_username << "]: " << say.txt_text << std::endl;
              if (is_newline) {
                std::cout << ">" << stdin_buffer << std::flush;
              } else {
                std::cout << ">" << std::flush;
              }
              break;
            default:
              break;
          }
        }

        memset(&receive_buffer, 0, SAY_MAX);
      } // end of if client_socket

    } // end of if result

  } // end of while

  return 0;
}<commit_msg>print input then set it to ""<commit_after>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"
#include "raw.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(char *input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  size_t input_size = strlen(input);
  for (size_t i = 0; i < input_size; i++) {
    if (input[i] != delimiter) {
      word += input[i];
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

void StripChar(char *input, char c) {
  size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
    if (input[i] == c) {
      input[i] = '\0';
    }
  }
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    cooked_mode();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "\n*Unknown command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
  char *input = (char *) "";
  char tmp_buffer[SAY_MAX];
  memset(&tmp_buffer, 0, SAY_MAX);

  char stdin_buffer[SAY_MAX + 1];
  char *stdin_buffer_position = stdin_buffer;

//  struct timeval timeout;
  fd_set read_set;
//  int file_desc = 0;
  int result;
  char receive_buffer[kBufferSize];
  memset(&receive_buffer, 0, kBufferSize);

//  char stdin_buffer[kBufferSize];
//  memset(&stdin_buffer, 0, kBufferSize);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  if (raw_mode() != 0){
    Error("client: error using raw mode");
  }

  std::cout << ">" << std::flush;

  while (1) {
    FD_ZERO(&read_set);
    FD_SET(client_socket, &read_set);
    FD_SET(STDIN_FILENO, &read_set);

    if ((result = select(client_socket + 1, &read_set, NULL, NULL, NULL)) < 0) {
      Error("client: problem using select");
    }

    if (result > 0) {
      if (FD_ISSET(STDIN_FILENO, &read_set)) {
        char c = (char) getchar();
        if (c == '\n') {
          *stdin_buffer_position++ = '\0';
          stdin_buffer_position = stdin_buffer;
          printf("\n");
          fflush(stdout);
          input = stdin_buffer;

          if (input[0] == '/') {
            if (!ProcessInput(input)) {
              break;
            }
          } else {
            // Send chat messages
            RequestSay(input);
          }
        } else if (stdin_buffer_position != stdin_buffer + SAY_MAX) {
          *stdin_buffer_position++ = c;
          printf("%c", c); // cout does not work
          fflush(stdout);
        }
      } else if (FD_ISSET(client_socket, &read_set)) {
        // Socket has data
        int read_size = read(client_socket, receive_buffer, kBufferSize);

        if (read_size != 0) {
          // TODO capture user input, store, clean input, then print buffer, afterward replace input
          struct text message;
          memcpy(&message, receive_buffer, sizeof(struct text));
          text_t text_type = message.txt_type;

          switch (text_type) {
            case TXT_SAY:
              struct text_say say;
              memcpy(&say, receive_buffer, sizeof(struct text_say));
              std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
              std::cout << "[" << say.txt_channel << "]" << "[" << say.txt_username << "]: " << say.txt_text << std::endl;
              std::cout << ">" << input << std::flush;
              input = (char *) "";
              break;
            default:
              break;
          }
        }

        memset(&receive_buffer, 0, SAY_MAX);
      } // end of if client_socket

    } // end of if result

  } // end of while

  return 0;
}<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <locale>
#include <string>
#include <vector>
#include <iv/stringpiece.h>
#include <iv/ustringpiece.h>
#include <iv/about.h>
#include <iv/cmdline.h>
#include <iv/lv5/lv5.h>
#include <iv/lv5/railgun/command.h>
#include <iv/lv5/railgun/interactive.h>
#include <iv/lv5/teleporter/interactive.h>
#include <iv/lv5/melt/melt.h>
#if defined(IV_OS_MACOSX) || defined(IV_OS_LINUX) || defined(IV_OS_BSD)
#include <signal.h>
#endif

namespace {

void InitContext(iv::lv5::Context* ctx) {
  iv::lv5::Error::Dummy dummy;
  ctx->DefineFunction<&iv::lv5::Print, 1>("print");
  ctx->DefineFunction<&iv::lv5::Log, 1>("log");  // this is simply output log function
  ctx->DefineFunction<&iv::lv5::Quit, 1>("quit");
  ctx->DefineFunction<&iv::lv5::CollectGarbage, 0>("gc");
  ctx->DefineFunction<&iv::lv5::HiResTime, 0>("HiResTime");
  ctx->DefineFunction<&iv::lv5::railgun::Dis, 1>("dis");
  ctx->DefineFunction<&iv::lv5::breaker::Run, 0>("run");
  iv::lv5::melt::Console::Export(ctx, &dummy);
}

#if defined(IV_ENABLE_JIT)
int BreakerExecute(const iv::core::StringPiece& data,
                   const std::string& filename, bool statistics) {
  iv::lv5::Error::Standard e;
  iv::lv5::breaker::Context ctx;
  InitContext(&ctx);
  std::shared_ptr<iv::core::FileSource>
      src(new iv::core::FileSource(data, filename));
  iv::lv5::breaker::ExecuteInGlobal(&ctx, src, &e);
  if (e) {
    e.Dump(&ctx, stderr);
    return EXIT_FAILURE;
  }
  ctx.Validate();
  return EXIT_SUCCESS;
}

int BreakerExecuteFiles(const std::vector<std::string>& filenames) {
  iv::lv5::Error::Standard e;
  iv::lv5::breaker::Context ctx;
  InitContext(&ctx);

  std::vector<char> res;
  for (std::vector<std::string>::const_iterator it = filenames.begin(),
       last = filenames.end(); it != last; ++it) {
    if (!iv::core::ReadFile(*it, &res)) {
      return EXIT_FAILURE;
    }
    std::shared_ptr<iv::core::FileSource>
        src(new iv::core::FileSource(
                iv::core::StringPiece(res.data(), res.size()), *it));
    res.clear();
    iv::lv5::breaker::ExecuteInGlobal(&ctx, src, &e);
    if (e) {
      e.Dump(&ctx, stderr);
      return EXIT_FAILURE;
    }
  }
  ctx.Validate();
  return EXIT_SUCCESS;
}
#endif

int RailgunExecute(const iv::core::StringPiece& data,
                   const std::string& filename, bool statistics) {
  iv::lv5::Error::Standard e;
  iv::lv5::railgun::Context ctx;
  InitContext(&ctx);

  std::shared_ptr<iv::core::FileSource>
      src(new iv::core::FileSource(data, filename));
  iv::lv5::railgun::ExecuteInGlobal(&ctx, src, &e);
  if (e) {
    e.Dump(&ctx, stderr);
    return EXIT_FAILURE;
  }
  if (statistics) {
    ctx.vm()->DumpStatistics();
  }
  ctx.Validate();
  return EXIT_SUCCESS;
}

int RailgunExecuteFiles(const std::vector<std::string>& filenames) {
  iv::lv5::Error::Standard e;
  iv::lv5::railgun::Context ctx;
  InitContext(&ctx);

  std::vector<char> res;
  for (std::vector<std::string>::const_iterator it = filenames.begin(),
       last = filenames.end(); it != last; ++it) {
    if (!iv::core::ReadFile(*it, &res)) {
      return EXIT_FAILURE;
    }
    std::shared_ptr<iv::core::FileSource>
        src(new iv::core::FileSource(
                iv::core::StringPiece(res.data(), res.size()), *it));
    res.clear();
    iv::lv5::railgun::ExecuteInGlobal(&ctx, src, &e);
    if (e) {
      e.Dump(&ctx, stderr);
      return EXIT_FAILURE;
    }
  }
  ctx.Validate();
  return EXIT_SUCCESS;
}

int DisAssemble(const iv::core::StringPiece& data,
                const std::string& filename) {
  iv::lv5::railgun::Context ctx;
  iv::lv5::Error::Standard e;
  std::shared_ptr<iv::core::FileSource>
      src(new iv::core::FileSource(data, filename));
  iv::lv5::railgun::Code* code =
      iv::lv5::railgun::CompileInGlobal(&ctx, src, true, &e);
  if (e) {
    return EXIT_FAILURE;
  }
  iv::lv5::railgun::OutputDisAssembler dis(&ctx, stdout);
  dis.DisAssembleGlobal(*code);
  return EXIT_SUCCESS;
}

int Interpret(const iv::core::StringPiece& data, const std::string& filename) {
  iv::core::FileSource src(data, filename);
  iv::lv5::teleporter::Context ctx;
  iv::lv5::AstFactory factory(&ctx);
  iv::core::Parser<iv::lv5::AstFactory,
                   iv::core::FileSource> parser(&factory,
                                                src, ctx.symbol_table());
  const iv::lv5::FunctionLiteral* const global = parser.ParseProgram();

  if (!global) {
    std::fprintf(stderr, "%s\n", parser.error().c_str());
    return EXIT_FAILURE;
  }
  ctx.DefineFunction<&iv::lv5::Print, 1>("print");
  ctx.DefineFunction<&iv::lv5::Quit, 1>("quit");
  ctx.DefineFunction<&iv::lv5::HiResTime, 0>("HiResTime");
  iv::lv5::teleporter::JSScript* const script =
      iv::lv5::teleporter::JSGlobalScript::New(&ctx, global, &factory, &src);
  if (ctx.Run(script)) {
    ctx.error()->Dump(&ctx, stderr);
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}

int Ast(const iv::core::StringPiece& data, const std::string& filename) {
  iv::core::FileSource src(data, filename);
  iv::lv5::railgun::Context ctx;
  iv::lv5::AstFactory factory(&ctx);
  iv::core::Parser<iv::lv5::AstFactory,
                   iv::core::FileSource> parser(&factory,
                                                src, ctx.symbol_table());
  const iv::lv5::FunctionLiteral* const global = parser.ParseProgram();

  if (!global) {
    std::fprintf(stderr, "%s\n", parser.error().c_str());
    return EXIT_FAILURE;
  }
  iv::core::ast::AstSerializer<iv::lv5::AstFactory> ser;
  ser.Visit(global);
  const iv::core::UString str = ser.out();
  iv::core::unicode::FPutsUTF16(stdout, str.begin(), str.end());
  return EXIT_SUCCESS;
}

}  // namespace anonymous

int main(int argc, char **argv) {
  iv::lv5::FPU fpu;
  iv::lv5::program::Init(argc, argv);
  iv::lv5::Init();

  iv::cmdline::Parser cmd("lv5");

  cmd.Add("help",
          "help",
          'h', "print this message");
  cmd.Add("version",
          "version",
          'v', "print the version");
  cmd.AddList<std::string>(
      "file",
      "file",
      'f', "script file to load");
  cmd.Add("signal",
          "",
          's', "install signal handlers");
  cmd.Add<std::string>(
      "execute",
      "execute",
      'e', "execute command", false);
  cmd.Add("ast",
          "ast",
          0, "print ast");
  cmd.Add("interp",
          "interp",
          0, "use interpreter");
  cmd.Add("railgun",
          "railgun",
          0, "force railgun VM");
  cmd.Add("dis",
          "dis",
          'd', "print bytecode");
  cmd.Add("statistics",
          "statistics",
          0, "print statistics");
  cmd.Add("copyright",
          "copyright",
          0,   "print the copyright");
  cmd.set_footer("[program_file] [arguments]");

  const bool cmd_parse_success = cmd.Parse(argc, argv);
  if (!cmd_parse_success) {
    std::fprintf(stderr, "%s\n%s",
                 cmd.error().c_str(), cmd.usage().c_str());
    return EXIT_FAILURE;
  }

  if (cmd.Exist("help")) {
    std::fputs(cmd.usage().c_str(), stdout);
    return EXIT_SUCCESS;
  }

  if (cmd.Exist("version")) {
    std::printf("lv5 %s (compiled %s %s)\n", IV_VERSION, __DATE__, __TIME__);
    return EXIT_SUCCESS;
  }

  if (cmd.Exist("copyright")) {
    std::printf("lv5 - %s\n", IV_COPYRIGHT);
    return EXIT_SUCCESS;
  }

  if (cmd.Exist("signal")) {
#if defined(IV_OS_MACOSX) || defined(IV_OS_LINUX) || defined(IV_OS_BSD)
    signal(SIGILL, _exit);
    signal(SIGFPE, _exit);
    signal(SIGBUS, _exit);
    signal(SIGSEGV, _exit);
#endif
  }

  const std::vector<std::string>& rest = cmd.rest();
  if (!rest.empty() || cmd.Exist("file") || cmd.Exist("execute")) {
    std::vector<char> res;
    std::string filename;
    if (cmd.Exist("file")) {
      const std::vector<std::string>& vec = cmd.GetList<std::string>("file");
      if (!cmd.Exist("ast") && !cmd.Exist("dis") && !cmd.Exist("interp")) {
        if (cmd.Exist("railgun")) {
          return RailgunExecuteFiles(vec);
        }
#if defined(IV_ENABLE_JIT)
        return BreakerExecuteFiles(vec);
#else
        return RailgunExecuteFiles(vec);
#endif
      }
      for (std::vector<std::string>::const_iterator it = vec.begin(),
           last = vec.end(); it != last; ++it, filename.push_back(' ')) {
        filename.append(*it);
        if (!iv::core::ReadFile(*it, &res)) {
          return EXIT_FAILURE;
        }
      }
    } else if (cmd.Exist("execute")) {
      const std::string& com = cmd.Get<std::string>("execute");
      filename = "<command>";
      res.insert(res.end(), com.begin(), com.end());
    } else {
      filename = rest.front();
      if (!iv::core::ReadFile(filename, &res)) {
        return EXIT_FAILURE;
      }
    }
    const iv::core::StringPiece src(res.data(), res.size());
    if (cmd.Exist("ast")) {
      return Ast(src, filename);
    } else if (cmd.Exist("dis")) {
      return DisAssemble(src, filename);
    } else if (cmd.Exist("interp")) {
      return Interpret(src, filename);
    } else if (cmd.Exist("railgun")) {
      return RailgunExecute(src, filename, cmd.Exist("statistics"));
    } else {
#if defined(IV_ENABLE_JIT)
      return BreakerExecute(src, filename, cmd.Exist("statistics"));
#else
      return RailgunExecute(src, filename, cmd.Exist("statistics"));
#endif
    }
  } else {
    // Interactive Shell Mode
    if (cmd.Exist("interp")) {
      iv::lv5::teleporter::Interactive shell;
      return shell.Run();
    } else {
      iv::lv5::railgun::Interactive shell(cmd.Exist("dis"));
      return shell.Run();
    }
  }
  return 0;
}
<commit_msg>Fix compile error in Windows<commit_after>#include <cstdio>
#include <cstdlib>
#include <locale>
#include <string>
#include <vector>
#include <iv/stringpiece.h>
#include <iv/ustringpiece.h>
#include <iv/about.h>
#include <iv/cmdline.h>
#include <iv/lv5/lv5.h>
#include <iv/lv5/teleporter/interactive.h>
#include <iv/lv5/railgun/command.h>
#include <iv/lv5/railgun/interactive.h>
#include <iv/lv5/breaker/command.h>
#include <iv/lv5/melt/melt.h>
#if defined(IV_OS_MACOSX) || defined(IV_OS_LINUX) || defined(IV_OS_BSD)
#include <signal.h>
#endif

namespace {

void InitContext(iv::lv5::Context* ctx) {
  iv::lv5::Error::Dummy dummy;
  ctx->DefineFunction<&iv::lv5::Print, 1>("print");
  ctx->DefineFunction<&iv::lv5::Log, 1>("log");  // this is simply output log function
  ctx->DefineFunction<&iv::lv5::Quit, 1>("quit");
  ctx->DefineFunction<&iv::lv5::CollectGarbage, 0>("gc");
  ctx->DefineFunction<&iv::lv5::HiResTime, 0>("HiResTime");
  ctx->DefineFunction<&iv::lv5::railgun::Dis, 1>("dis");
  ctx->DefineFunction<&iv::lv5::breaker::Run, 0>("run");
  iv::lv5::melt::Console::Export(ctx, &dummy);
}

#if defined(IV_ENABLE_JIT)
int BreakerExecute(const iv::core::StringPiece& data,
                   const std::string& filename, bool statistics) {
  iv::lv5::Error::Standard e;
  iv::lv5::breaker::Context ctx;
  InitContext(&ctx);
  std::shared_ptr<iv::core::FileSource>
      src(new iv::core::FileSource(data, filename));
  iv::lv5::breaker::ExecuteInGlobal(&ctx, src, &e);
  if (e) {
    e.Dump(&ctx, stderr);
    return EXIT_FAILURE;
  }
  ctx.Validate();
  return EXIT_SUCCESS;
}

int BreakerExecuteFiles(const std::vector<std::string>& filenames) {
  iv::lv5::Error::Standard e;
  iv::lv5::breaker::Context ctx;
  InitContext(&ctx);

  std::vector<char> res;
  for (std::vector<std::string>::const_iterator it = filenames.begin(),
       last = filenames.end(); it != last; ++it) {
    if (!iv::core::ReadFile(*it, &res)) {
      return EXIT_FAILURE;
    }
    std::shared_ptr<iv::core::FileSource>
        src(new iv::core::FileSource(
                iv::core::StringPiece(res.data(), res.size()), *it));
    res.clear();
    iv::lv5::breaker::ExecuteInGlobal(&ctx, src, &e);
    if (e) {
      e.Dump(&ctx, stderr);
      return EXIT_FAILURE;
    }
  }
  ctx.Validate();
  return EXIT_SUCCESS;
}
#endif

int RailgunExecute(const iv::core::StringPiece& data,
                   const std::string& filename, bool statistics) {
  iv::lv5::Error::Standard e;
  iv::lv5::railgun::Context ctx;
  InitContext(&ctx);

  std::shared_ptr<iv::core::FileSource>
      src(new iv::core::FileSource(data, filename));
  iv::lv5::railgun::ExecuteInGlobal(&ctx, src, &e);
  if (e) {
    e.Dump(&ctx, stderr);
    return EXIT_FAILURE;
  }
  if (statistics) {
    ctx.vm()->DumpStatistics();
  }
  ctx.Validate();
  return EXIT_SUCCESS;
}

int RailgunExecuteFiles(const std::vector<std::string>& filenames) {
  iv::lv5::Error::Standard e;
  iv::lv5::railgun::Context ctx;
  InitContext(&ctx);

  std::vector<char> res;
  for (std::vector<std::string>::const_iterator it = filenames.begin(),
       last = filenames.end(); it != last; ++it) {
    if (!iv::core::ReadFile(*it, &res)) {
      return EXIT_FAILURE;
    }
    std::shared_ptr<iv::core::FileSource>
        src(new iv::core::FileSource(
                iv::core::StringPiece(res.data(), res.size()), *it));
    res.clear();
    iv::lv5::railgun::ExecuteInGlobal(&ctx, src, &e);
    if (e) {
      e.Dump(&ctx, stderr);
      return EXIT_FAILURE;
    }
  }
  ctx.Validate();
  return EXIT_SUCCESS;
}

int DisAssemble(const iv::core::StringPiece& data,
                const std::string& filename) {
  iv::lv5::railgun::Context ctx;
  iv::lv5::Error::Standard e;
  std::shared_ptr<iv::core::FileSource>
      src(new iv::core::FileSource(data, filename));
  iv::lv5::railgun::Code* code =
      iv::lv5::railgun::CompileInGlobal(&ctx, src, true, &e);
  if (e) {
    return EXIT_FAILURE;
  }
  iv::lv5::railgun::OutputDisAssembler dis(&ctx, stdout);
  dis.DisAssembleGlobal(*code);
  return EXIT_SUCCESS;
}

int Interpret(const iv::core::StringPiece& data, const std::string& filename) {
  iv::core::FileSource src(data, filename);
  iv::lv5::teleporter::Context ctx;
  iv::lv5::AstFactory factory(&ctx);
  iv::core::Parser<iv::lv5::AstFactory,
                   iv::core::FileSource> parser(&factory,
                                                src, ctx.symbol_table());
  const iv::lv5::FunctionLiteral* const global = parser.ParseProgram();

  if (!global) {
    std::fprintf(stderr, "%s\n", parser.error().c_str());
    return EXIT_FAILURE;
  }
  ctx.DefineFunction<&iv::lv5::Print, 1>("print");
  ctx.DefineFunction<&iv::lv5::Quit, 1>("quit");
  ctx.DefineFunction<&iv::lv5::HiResTime, 0>("HiResTime");
  iv::lv5::teleporter::JSScript* const script =
      iv::lv5::teleporter::JSGlobalScript::New(&ctx, global, &factory, &src);
  if (ctx.Run(script)) {
    ctx.error()->Dump(&ctx, stderr);
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}

int Ast(const iv::core::StringPiece& data, const std::string& filename) {
  iv::core::FileSource src(data, filename);
  iv::lv5::railgun::Context ctx;
  iv::lv5::AstFactory factory(&ctx);
  iv::core::Parser<iv::lv5::AstFactory,
                   iv::core::FileSource> parser(&factory,
                                                src, ctx.symbol_table());
  const iv::lv5::FunctionLiteral* const global = parser.ParseProgram();

  if (!global) {
    std::fprintf(stderr, "%s\n", parser.error().c_str());
    return EXIT_FAILURE;
  }
  iv::core::ast::AstSerializer<iv::lv5::AstFactory> ser;
  ser.Visit(global);
  const iv::core::UString str = ser.out();
  iv::core::unicode::FPutsUTF16(stdout, str.begin(), str.end());
  return EXIT_SUCCESS;
}

}  // namespace anonymous

int main(int argc, char **argv) {
  iv::lv5::FPU fpu;
  iv::lv5::program::Init(argc, argv);
  iv::lv5::Init();

  iv::cmdline::Parser cmd("lv5");

  cmd.Add("help",
          "help",
          'h', "print this message");
  cmd.Add("version",
          "version",
          'v', "print the version");
  cmd.AddList<std::string>(
      "file",
      "file",
      'f', "script file to load");
  cmd.Add("signal",
          "",
          's', "install signal handlers");
  cmd.Add<std::string>(
      "execute",
      "execute",
      'e', "execute command", false);
  cmd.Add("ast",
          "ast",
          0, "print ast");
  cmd.Add("interp",
          "interp",
          0, "use interpreter");
  cmd.Add("railgun",
          "railgun",
          0, "force railgun VM");
  cmd.Add("dis",
          "dis",
          'd', "print bytecode");
  cmd.Add("statistics",
          "statistics",
          0, "print statistics");
  cmd.Add("copyright",
          "copyright",
          0,   "print the copyright");
  cmd.set_footer("[program_file] [arguments]");

  const bool cmd_parse_success = cmd.Parse(argc, argv);
  if (!cmd_parse_success) {
    std::fprintf(stderr, "%s\n%s",
                 cmd.error().c_str(), cmd.usage().c_str());
    return EXIT_FAILURE;
  }

  if (cmd.Exist("help")) {
    std::fputs(cmd.usage().c_str(), stdout);
    return EXIT_SUCCESS;
  }

  if (cmd.Exist("version")) {
    std::printf("lv5 %s (compiled %s %s)\n", IV_VERSION, __DATE__, __TIME__);
    return EXIT_SUCCESS;
  }

  if (cmd.Exist("copyright")) {
    std::printf("lv5 - %s\n", IV_COPYRIGHT);
    return EXIT_SUCCESS;
  }

  if (cmd.Exist("signal")) {
#if defined(IV_OS_MACOSX) || defined(IV_OS_LINUX) || defined(IV_OS_BSD)
    signal(SIGILL, _exit);
    signal(SIGFPE, _exit);
    signal(SIGBUS, _exit);
    signal(SIGSEGV, _exit);
#endif
  }

  const std::vector<std::string>& rest = cmd.rest();
  if (!rest.empty() || cmd.Exist("file") || cmd.Exist("execute")) {
    std::vector<char> res;
    std::string filename;
    if (cmd.Exist("file")) {
      const std::vector<std::string>& vec = cmd.GetList<std::string>("file");
      if (!cmd.Exist("ast") && !cmd.Exist("dis") && !cmd.Exist("interp")) {
        if (cmd.Exist("railgun")) {
          return RailgunExecuteFiles(vec);
        }
#if defined(IV_ENABLE_JIT)
        return BreakerExecuteFiles(vec);
#else
        return RailgunExecuteFiles(vec);
#endif
      }
      for (std::vector<std::string>::const_iterator it = vec.begin(),
           last = vec.end(); it != last; ++it, filename.push_back(' ')) {
        filename.append(*it);
        if (!iv::core::ReadFile(*it, &res)) {
          return EXIT_FAILURE;
        }
      }
    } else if (cmd.Exist("execute")) {
      const std::string& com = cmd.Get<std::string>("execute");
      filename = "<command>";
      res.insert(res.end(), com.begin(), com.end());
    } else {
      filename = rest.front();
      if (!iv::core::ReadFile(filename, &res)) {
        return EXIT_FAILURE;
      }
    }
    const iv::core::StringPiece src(res.data(), res.size());
    if (cmd.Exist("ast")) {
      return Ast(src, filename);
    } else if (cmd.Exist("dis")) {
      return DisAssemble(src, filename);
    } else if (cmd.Exist("interp")) {
      return Interpret(src, filename);
    } else if (cmd.Exist("railgun")) {
      return RailgunExecute(src, filename, cmd.Exist("statistics"));
    } else {
#if defined(IV_ENABLE_JIT)
      return BreakerExecute(src, filename, cmd.Exist("statistics"));
#else
      return RailgunExecute(src, filename, cmd.Exist("statistics"));
#endif
    }
  } else {
    // Interactive Shell Mode
    if (cmd.Exist("interp")) {
      iv::lv5::teleporter::Interactive shell;
      return shell.Run();
    } else {
      iv::lv5::railgun::Interactive shell(cmd.Exist("dis"));
      return shell.Run();
    }
  }
  return 0;
}
<|endoftext|>


<commit_before>
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Guido Tack <guido.tack@monash.edu>
 *     Gleb Belov <gleb.belov@monash.edu>
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* This (main) file coordinates flattening and solving.
 * The corresponding modules are flexibly plugged in
 * as derived classes, prospectively from DLLs.
 * A flattening module should provide MinZinc::GetFlattener()
 * A solving module should provide an object of a class derived from SolverFactory.
 * Need to get more flexible for multi-pass & multi-solving stuff  TODO
 */

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>

using namespace std;

#include <minizinc/solver.hh>

using namespace MiniZinc;

int main(int argc, const char** argv) {
  clock_t starttime = std::clock(), endTime;
  bool fSuccess = false;

  MznSolver slv;
  try {

    slv.addFlattener();
    if (!slv.processOptions(argc, argv)) {
      slv.printHelp();
      exit(EXIT_FAILURE);
    }
    slv.flatten();

    if (SolverInstance::UNKNOWN == slv.getFlt()->status)
    {
      fSuccess = true;
      if ( !slv.ifMzn2Fzn() ) {          // only then
        GCLock lock;
        slv.addSolverInterface();
        slv.solve();
      }
    } else if (SolverInstance::ERROR == slv.getFlt()->status) {
//       slv.s2out.evalStatus( slv.getFlt()->status );
    } else {
      fSuccess = true;
//       slv.s2out.evalStatus( slv.getFlt()->status );
    }   // TODO  Move evalOutput() here?
  } catch (const LocationException& e) {
    if (slv.get_flag_verbose())
      std::cerr << std::endl;
    std::cerr << e.loc() << ":" << std::endl;
    std::cerr << e.what() << ": " << e.msg() << std::endl;
    slv.s2out.evalStatus( SolverInstance::ERROR );
  } catch (const Exception& e) {
    if (slv.get_flag_verbose())
      std::cerr << std::endl;
    std::cerr << e.what() << ": " << e.msg() << std::endl;
    slv.s2out.evalStatus( SolverInstance::ERROR );
  }
  catch (const exception& e) {
    if (slv.get_flag_verbose())
      std::cerr << std::endl;
    std::cerr << e.what() << std::endl;
    slv.s2out.evalStatus( SolverInstance::ERROR );
  }
  catch (...) {
    if (slv.get_flag_verbose())
      std::cerr << std::endl;
    std::cerr << "  UNKNOWN EXCEPTION." << std::endl;
    slv.s2out.evalStatus( SolverInstance::ERROR );
  }

  if ( !slv.ifMzn2Fzn() ) {
    endTime = clock();
    if (slv.get_flag_verbose()) {
      std::cerr << "   Done (";
      cerr << "overall time " << timeDiff(endTime, starttime) << ")." << std::endl;
    }
  }
  return !fSuccess;
}   // int main()

// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SolverRegistry* MiniZinc::getGlobalSolverRegistry()
{
  static SolverRegistry sr;
  return &sr;
}

void SolverRegistry::addSolverFactory(SolverFactory* pSF)
{
  assert(pSF);
  sfstorage.push_back(pSF);
}

void SolverRegistry::removeSolverFactory(SolverFactory* pSF)
{
  auto it = find(sfstorage.begin(), sfstorage.end(), pSF);
  assert(pSF);
  sfstorage.erase(it);
}

/// Function createSI also adds each SI to the local storage
SolverInstanceBase * SolverFactory::createSI(Env& env) {
  SolverInstanceBase *pSI = doCreateSI(env);
  if (!pSI) {
    cerr << "  SolverFactory: failed to initialize solver "
      << getVersion() << endl;
    throw InternalError("  SolverFactory: failed to initialize solver");
  }
  sistorage.resize(sistorage.size()+1);
  sistorage.back().reset(pSI);
  return pSI;
}

/// also providing a destroy function for a DLL or just special allocator etc.
void SolverFactory::destroySI(SolverInstanceBase * pSI) {
  auto it = sistorage.begin();
  for ( ; it != sistorage.end(); ++ it)
    if (it->get() == pSI)
      break;
  if (sistorage.end() == it) {
    cerr << "  SolverFactory: failed to remove solver at "
      << pSI << endl;
    throw InternalError("  SolverFactory: failed to remove solver");
  }
  sistorage.erase(it);
}

MznSolver::~MznSolver()
{
//   if (si)                         // first the solver
//     CleanupSolverInterface(si);
  // TODO cleanup the used solver interfaces
  si=0;
  if (flt)
    cleanupGlobalFlattener(flt);
  flt=0;
}

bool MznSolver::ifMzn2Fzn() {
#ifdef FLATTEN_ONLY
  return true;
#else
  return 0==getNSolvers();
#endif
}

void MznSolver::addFlattener()
{
  flt = getGlobalFlattener(ifMzn2Fzn());
  assert(flt);
}

void MznSolver::addSolverInterface()
{
  assert(getGlobalSolverRegistry()->getSolverFactories().size());
  si = getGlobalSolverRegistry()->getSolverFactories().front()->createSI(*flt->getEnv());
  assert(si);
  s2out.initFromEnv( flt->getEnv() );
  si->setSolns2Out( &s2out );
  if (get_flag_verbose())
    cerr
//     << "  ---------------------------------------------------------------------------\n"
    << "      % SOLVING PHASE\n"
    << getGlobalSolverRegistry()->getSolverFactories().front()->getVersion() << endl;
}

void MznSolver::printHelp()
{
  if ( !ifMzn2Fzn() )
  cout
    << "NICTA MiniZinc driver.\n"
    << "Usage: <executable>"  //<< argv[0]
    << "  [<options>] [-I <include path>] <model>.mzn [<data>.dzn ...] or just <flat>.fzn" << std::endl;
  else
  cout
    << "NICTA MiniZinc to FlatZinc converter.\n"
    << "Usage: <executable>"  //<< argv[0]
    << "  [<options>] [-I <include path>] <model>.mzn [<data>.dzn ...]" << std::endl;
  cout
    << "Options:" << std::endl
    << "  --help, -h\n    Print this help message." << std::endl
    << "  --version\n    Print version information." << std::endl
    << "  -v, -l, --verbose\n    Print progress/log statements. Note that some solvers may log to stdout." << std::endl
    << "  -s, --statistics\n    Print statistics." << std::endl;
//   if ( getNSolvers() )

  getFlt()->printHelp(cout);
  cout << endl;
  if ( !ifMzn2Fzn() ) {
    s2out.printHelp(cout);
    cout << endl;
  }
  for (auto it = getGlobalSolverRegistry()->getSolverFactories().begin();
        it != getGlobalSolverRegistry()->getSolverFactories().end(); ++it) {
       (*it)->printHelp(cout);
      cout << endl;
  }
}

bool MznSolver::processOptions(int argc, const char** argv)
{
  int i=1;
  if (argc < 2)
    return false;
  for (i=1; i<argc; ++i) {
    if (string(argv[i])=="-h" || string(argv[i])=="--help") {
      printHelp();
      std::exit(EXIT_SUCCESS);
    }
    if (string(argv[i])=="--version") {
      getFlt()->printVersion(cout);
      for (auto it = getGlobalSolverRegistry()->getSolverFactories().begin();
           it != getGlobalSolverRegistry()->getSolverFactories().end(); ++it)
        cout << (*it)->getVersion() << endl;
      std::exit(EXIT_SUCCESS);
    }
    //  moving --verbose here:
    if ((argv[i])==string("-v") || (argv[i])==string("--verbose") || (argv[i])==string("-l")) {
      flag_verbose = true;
    } else if (string(argv[i])=="-s" || string(argv[i])=="--statistics") {
      flag_statistics = true;                  // is this Flattener's option?
    } else if ( !ifMzn2Fzn() ? s2out.processOption( i, argc, argv ) : false ) {
    } else if (!getFlt()->processOption(i, argc, argv)) {
      for (auto it = getGlobalSolverRegistry()->getSolverFactories().begin();
           it != getGlobalSolverRegistry()->getSolverFactories().end(); ++it)
        if ((*it)->processOption(i, argc, argv))
          goto Found;
      goto NotFound;
    }
Found: { }
  }
  return true;
NotFound:
  cerr << "  Unrecognized option: '" << argv[i] << "'" << endl;
  return false;
}

void MznSolver::flatten()
{
  getFlt()->set_flag_verbose(get_flag_verbose());
  getFlt()->set_flag_statistics(get_flag_statistics());
  clock_t tm01 = clock();
  getFlt()->flatten();
  if (get_flag_verbose())
    std::cerr << "  Flattening done, " << timeDiff(clock(), tm01) << std::endl;

}

void MznSolver::solve()
{
  GCLock lock;
  getSI()->getOptions().setBoolParam  (constants().opts.verbose.str(),  get_flag_verbose());
  getSI()->getOptions().setBoolParam  (constants().opts.statistics.str(),  get_flag_statistics());
  getSI()->processFlatZinc();
  SolverInstance::Status status = getSI()->solve();
  if (status==SolverInstance::SAT || status==SolverInstance::OPT) {
    getSI()->printSolution();             // What if it's already printed?  TODO
    if ( !getSI()->getSolns2Out()->fStatusPrinted )
      getSI()->getSolns2Out()->evalStatus( status );
  }
  else {
    if ( !getSI()->getSolns2Out()->fStatusPrinted )
      getSI()->getSolns2Out()->evalStatus( status );
    if (get_flag_statistics())    // it's summary in fact
      printStatistics();
  }
}

void MznSolver::printStatistics()
{ // from flattener too?   TODO
  if (si)
    getSI()->printStatisticsLine(cout, 1);
}

<commit_msg>mzn2fzn evaluates solution status (prints status message) if not UNKNOWN<commit_after>
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Guido Tack <guido.tack@monash.edu>
 *     Gleb Belov <gleb.belov@monash.edu>
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* This (main) file coordinates flattening and solving.
 * The corresponding modules are flexibly plugged in
 * as derived classes, prospectively from DLLs.
 * A flattening module should provide MinZinc::GetFlattener()
 * A solving module should provide an object of a class derived from SolverFactory.
 * Need to get more flexible for multi-pass & multi-solving stuff  TODO
 */

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>

using namespace std;

#include <minizinc/solver.hh>

using namespace MiniZinc;

int main(int argc, const char** argv) {
  clock_t starttime = std::clock(), endTime;
  bool fSuccess = false;

  MznSolver slv;
  try {

    slv.addFlattener();
    if (!slv.processOptions(argc, argv)) {
      slv.printHelp();
      exit(EXIT_FAILURE);
    }
    slv.flatten();

    if (SolverInstance::UNKNOWN == slv.getFlt()->status)
    {
      fSuccess = true;
      if ( !slv.ifMzn2Fzn() ) {          // only then
        GCLock lock;
        slv.addSolverInterface();
        slv.solve();
      }
    } else if (SolverInstance::ERROR == slv.getFlt()->status) {
      slv.s2out.evalStatus( slv.getFlt()->status );
    } else {
      fSuccess = true;
      slv.s2out.evalStatus( slv.getFlt()->status );
    }   // TODO  Move evalOutput() here?
  } catch (const LocationException& e) {
    if (slv.get_flag_verbose())
      std::cerr << std::endl;
    std::cerr << e.loc() << ":" << std::endl;
    std::cerr << e.what() << ": " << e.msg() << std::endl;
    slv.s2out.evalStatus( SolverInstance::ERROR );
  } catch (const Exception& e) {
    if (slv.get_flag_verbose())
      std::cerr << std::endl;
    std::cerr << e.what() << ": " << e.msg() << std::endl;
    slv.s2out.evalStatus( SolverInstance::ERROR );
  }
  catch (const exception& e) {
    if (slv.get_flag_verbose())
      std::cerr << std::endl;
    std::cerr << e.what() << std::endl;
    slv.s2out.evalStatus( SolverInstance::ERROR );
  }
  catch (...) {
    if (slv.get_flag_verbose())
      std::cerr << std::endl;
    std::cerr << "  UNKNOWN EXCEPTION." << std::endl;
    slv.s2out.evalStatus( SolverInstance::ERROR );
  }

  if ( !slv.ifMzn2Fzn() ) {
    endTime = clock();
    if (slv.get_flag_verbose()) {
      std::cerr << "   Done (";
      cerr << "overall time " << timeDiff(endTime, starttime) << ")." << std::endl;
    }
  }
  return !fSuccess;
}   // int main()

// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SolverRegistry* MiniZinc::getGlobalSolverRegistry()
{
  static SolverRegistry sr;
  return &sr;
}

void SolverRegistry::addSolverFactory(SolverFactory* pSF)
{
  assert(pSF);
  sfstorage.push_back(pSF);
}

void SolverRegistry::removeSolverFactory(SolverFactory* pSF)
{
  auto it = find(sfstorage.begin(), sfstorage.end(), pSF);
  assert(pSF);
  sfstorage.erase(it);
}

/// Function createSI also adds each SI to the local storage
SolverInstanceBase * SolverFactory::createSI(Env& env) {
  SolverInstanceBase *pSI = doCreateSI(env);
  if (!pSI) {
    cerr << "  SolverFactory: failed to initialize solver "
      << getVersion() << endl;
    throw InternalError("  SolverFactory: failed to initialize solver");
  }
  sistorage.resize(sistorage.size()+1);
  sistorage.back().reset(pSI);
  return pSI;
}

/// also providing a destroy function for a DLL or just special allocator etc.
void SolverFactory::destroySI(SolverInstanceBase * pSI) {
  auto it = sistorage.begin();
  for ( ; it != sistorage.end(); ++ it)
    if (it->get() == pSI)
      break;
  if (sistorage.end() == it) {
    cerr << "  SolverFactory: failed to remove solver at "
      << pSI << endl;
    throw InternalError("  SolverFactory: failed to remove solver");
  }
  sistorage.erase(it);
}

MznSolver::~MznSolver()
{
//   if (si)                         // first the solver
//     CleanupSolverInterface(si);
  // TODO cleanup the used solver interfaces
  si=0;
  if (flt)
    cleanupGlobalFlattener(flt);
  flt=0;
}

bool MznSolver::ifMzn2Fzn() {
#ifdef FLATTEN_ONLY
  return true;
#else
  return 0==getNSolvers();
#endif
}

void MznSolver::addFlattener()
{
  flt = getGlobalFlattener(ifMzn2Fzn());
  assert(flt);
}

void MznSolver::addSolverInterface()
{
  assert(getGlobalSolverRegistry()->getSolverFactories().size());
  si = getGlobalSolverRegistry()->getSolverFactories().front()->createSI(*flt->getEnv());
  assert(si);
  s2out.initFromEnv( flt->getEnv() );
  si->setSolns2Out( &s2out );
  if (get_flag_verbose())
    cerr
//     << "  ---------------------------------------------------------------------------\n"
    << "      % SOLVING PHASE\n"
    << getGlobalSolverRegistry()->getSolverFactories().front()->getVersion() << endl;
}

void MznSolver::printHelp()
{
  if ( !ifMzn2Fzn() )
  cout
    << "NICTA MiniZinc driver.\n"
    << "Usage: <executable>"  //<< argv[0]
    << "  [<options>] [-I <include path>] <model>.mzn [<data>.dzn ...] or just <flat>.fzn" << std::endl;
  else
  cout
    << "NICTA MiniZinc to FlatZinc converter.\n"
    << "Usage: <executable>"  //<< argv[0]
    << "  [<options>] [-I <include path>] <model>.mzn [<data>.dzn ...]" << std::endl;
  cout
    << "Options:" << std::endl
    << "  --help, -h\n    Print this help message." << std::endl
    << "  --version\n    Print version information." << std::endl
    << "  -v, -l, --verbose\n    Print progress/log statements. Note that some solvers may log to stdout." << std::endl
    << "  -s, --statistics\n    Print statistics." << std::endl;
//   if ( getNSolvers() )

  getFlt()->printHelp(cout);
  cout << endl;
  if ( !ifMzn2Fzn() ) {
    s2out.printHelp(cout);
    cout << endl;
  }
  for (auto it = getGlobalSolverRegistry()->getSolverFactories().begin();
        it != getGlobalSolverRegistry()->getSolverFactories().end(); ++it) {
       (*it)->printHelp(cout);
      cout << endl;
  }
}

bool MznSolver::processOptions(int argc, const char** argv)
{
  int i=1;
  if (argc < 2)
    return false;
  for (i=1; i<argc; ++i) {
    if (string(argv[i])=="-h" || string(argv[i])=="--help") {
      printHelp();
      std::exit(EXIT_SUCCESS);
    }
    if (string(argv[i])=="--version") {
      getFlt()->printVersion(cout);
      for (auto it = getGlobalSolverRegistry()->getSolverFactories().begin();
           it != getGlobalSolverRegistry()->getSolverFactories().end(); ++it)
        cout << (*it)->getVersion() << endl;
      std::exit(EXIT_SUCCESS);
    }
    //  moving --verbose here:
    if ((argv[i])==string("-v") || (argv[i])==string("--verbose") || (argv[i])==string("-l")) {
      flag_verbose = true;
    } else if (string(argv[i])=="-s" || string(argv[i])=="--statistics") {
      flag_statistics = true;                  // is this Flattener's option?
    } else if ( !ifMzn2Fzn() ? s2out.processOption( i, argc, argv ) : false ) {
    } else if (!getFlt()->processOption(i, argc, argv)) {
      for (auto it = getGlobalSolverRegistry()->getSolverFactories().begin();
           it != getGlobalSolverRegistry()->getSolverFactories().end(); ++it)
        if ((*it)->processOption(i, argc, argv))
          goto Found;
      goto NotFound;
    }
Found: { }
  }
  return true;
NotFound:
  cerr << "  Unrecognized option or bad format: '" << argv[i] << "'" << endl;
  return false;
}

void MznSolver::flatten()
{
  getFlt()->set_flag_verbose(get_flag_verbose());
  getFlt()->set_flag_statistics(get_flag_statistics());
  clock_t tm01 = clock();
  getFlt()->flatten();
  if (get_flag_verbose())
    std::cerr << "  Flattening done, " << timeDiff(clock(), tm01) << std::endl;

}

void MznSolver::solve()
{
  GCLock lock;
  getSI()->getOptions().setBoolParam  (constants().opts.verbose.str(),  get_flag_verbose());
  getSI()->getOptions().setBoolParam  (constants().opts.statistics.str(),  get_flag_statistics());
  getSI()->processFlatZinc();
  SolverInstance::Status status = getSI()->solve();
  if (status==SolverInstance::SAT || status==SolverInstance::OPT) {
    getSI()->printSolution();             // What if it's already printed?  TODO
    if ( !getSI()->getSolns2Out()->fStatusPrinted )
      getSI()->getSolns2Out()->evalStatus( status );
  }
  else {
    if ( !getSI()->getSolns2Out()->fStatusPrinted )
      getSI()->getSolns2Out()->evalStatus( status );
    if (get_flag_statistics())    // it's summary in fact
      printStatistics();
  }
}

void MznSolver::printStatistics()
{ // from flattener too?   TODO
  if (si)
    getSI()->printStatisticsLine(cout, 1);
}

<|endoftext|>