<commit_before>/**
 * @file
 * @author Jason Lingle
 * @brief Implementation of src/core/init_state.hxx
 */

#include <iostream>
#include <typeinfo>
#include <ctime>
#include <new>
#include <algorithm>

#include <GL/gl.h>
#include <SDL.h>

#include <tcl.h>

#include "init_state.hxx"
#include "src/abendstern.hxx"
#include "src/globals.hxx"
#include "src/graphics/imgload.hxx"
#include "src/test_state.hxx"
#include "src/fasttrig.hxx"
#include "src/background/background_object.hxx"
#include "src/background/star_field.hxx"
#include "src/background/explosion_pool.hxx"
#include "src/ship/sys/system_textures.hxx"
#include "src/graphics/vec.hxx"
#include "src/graphics/mat.hxx"
#include "src/graphics/matops.hxx"
#include "src/graphics/shader.hxx"
#include "src/graphics/cmn_shaders.hxx"
#include "src/graphics/glhelp.hxx"
#include "src/graphics/gl32emu.hxx"
#include "src/graphics/font.hxx"
#include "src/graphics/asgi.hxx"
#include "src/audio/audio.hxx"
#include "src/secondary/namegen.hxx"
#include "src/tcl_iface/bridge.hxx"
#include "src/exit_conditions.hxx"

using namespace std;

#if defined(AB_OPENGL_14)
#define LOGO "images/a14.png"
#elif defined(AB_OPENGL_21)
#define LOGO "images/a21.png"
#else
#define LOGO "images/a.png"
#endif

#define PRELIM_LOGO "images/a.png"

//For LSD-mode Easter Egg
static bool hasPressedL=false, hasPressedS=false, hasPressedD=false;

InitState::InitState() {
  currStep = 0;
  currStepProgress = 0;

  static float (*const stepsToLoad[])() = {
    &InitState::miscLoader,
    &InitState::initFontLoader,
    &InitState::systexLoader,
    &InitState::starLoader,
    &InitState::backgroundLoader,
    &InitState::keyboardDelay,
  };
  steps = stepsToLoad;
  numSteps = lenof(stepsToLoad);

  hasPainted=headless;
  if (!headless) {
    if (!preliminaryRunMode)
      SDL_ShowCursor(SDL_DISABLE);
    glGenTextures(1, &logo);
    vao = newVAO();
    glBindVertexArray(vao);
    vbo = newVBO();
    const char* error=loadImage(preliminaryRunMode? PRELIM_LOGO : LOGO, logo);
    if (error) {
      cerr << error << endl;
      exit(EXIT_MALFORMED_DATA);
    }
    //We can't set the buffer up yet, because vheight
    //has not yet been calculated.
  }
}

InitState::~InitState() {
  if (!headless) {
    glDeleteTextures(1, &logo);
    glDeleteBuffers(1, &vbo);
    glDeleteVertexArrays(1, &vao);
  }
}

GameState* InitState::update(float) {
  if (!hasPainted && !headless) return NULL;

  if (currStep < numSteps) {
    currStepProgress = steps[currStep]();
    if (currStepProgress > 1.0f) {
      currStepProgress = 0;
      ++currStep;
    }
  } else {
    if (hasPressedL && hasPressedS && hasPressedD) {
      enableLSDMode();
      shader::textureReplace.unload();
      shader::basic.unload();
    }

    //Start the root interpreter
    Tcl_Interp* root=newInterpreter(false);
    if (TCL_ERROR == Tcl_EvalFile(root, "tcl/autoexec.tcl")) {
      cerr << "FATAL: Autoexec did not run successfully: " << Tcl_GetStringResult(root) << endl;
      Tcl_Obj* options=Tcl_GetReturnOptions(root, TCL_ERROR);
      Tcl_Obj* key=Tcl_NewStringObj("-errorinfo", -1);
      Tcl_Obj* stackTrace;
      Tcl_IncrRefCount(key);
      Tcl_DictObjGet(NULL, options, key, &stackTrace);
      Tcl_DecrRefCount(key);
      cerr << "Stack trace:\n" << Tcl_GetStringFromObj(stackTrace, NULL) << endl;
      exit(EXIT_SCRIPTING_BUG);
    }
    if (this == state) {
      cerr << "FATAL: Autoexec did not change GameState" << endl;
      exit(EXIT_SCRIPTING_BUG);
    }
    if (!headless) {
      SDL_EnableUNICODE(1);
      SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
      //Tcl is taking over in a somewhat rude way, so
      //handle as gracefully as possible
      state->configureGL();
    }
  }

  return NULL;
}

void InitState::draw() {
  hasPainted=true;

  const shader::textureReplaceV quad[4] = {
      { {{0.5f-vheight/2,0      ,0,1}}, {{0,1}} },
      { {{0.5f+vheight/2,0      ,0,1}}, {{1,1}} },
      { {{0.5f-vheight/2,vheight,0,1}}, {{0,0}} },
      { {{0.5f+vheight/2,vheight,0,1}}, {{1,0}} },
  };

  shader::textureReplaceU uni;
  uni.colourMap=0;

  glBindVertexArray(vao);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
  shader::textureReplace->setupVBO();
  glBindTexture(GL_TEXTURE_2D, logo);
  shader::textureReplace->activate(&uni);
  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

  static const float progressH = 0.02f;
  static const float progressW = 0.3f;
  float currProgress = currStep/(float)numSteps + currStepProgress/numSteps;
  float baseX = 0.5f - progressW/2;
  #if defined(AB_OPENGL_14)
  asgi::colour(1.0f, 0.4f, 0.2f, 0.75f);
  #elif defined(AB_OPENGL_21)
  asgi::colour(0.2f, 1.0f, 0.4f, 0.75f);
  #else
  asgi::colour(0.2f, 0.3f, 0.9f, 0.75f);
  #endif
  asgi::begin(asgi::Quads);
  asgi::vertex(baseX, 4*progressH);
  asgi::vertex(baseX, 5*progressH);
  asgi::vertex(baseX + currProgress*progressW, 5*progressH);
  asgi::vertex(baseX + currProgress*progressW, 4*progressH);
  asgi::end();
  asgi::begin(asgi::Quads);
  asgi::vertex(baseX, 2.75f*progressH);
  asgi::vertex(baseX, 3.75f*progressH);
  asgi::vertex(baseX + currStepProgress*progressW, 3.75*progressH);
  asgi::vertex(baseX + currStepProgress*progressW, 2.75*progressH);
  asgi::end();
}

void InitState::keyboard(SDL_KeyboardEvent* e) {
  if (e->keysym.sym == SDLK_l)
    hasPressedL = true;
  else if (e->keysym.sym == SDLK_s)
    hasPressedS = true;
  else if (e->keysym.sym == SDLK_d)
    hasPressedD = true;
}

float InitState::miscLoader() {
  initTable(); //Trig tables
  sparkCountMultiplier=1;
  if (conf["conf"]["audio_enabled"]) audio::init();
  prepareTclBridge();
  namegenLoad();
  return 2;
}

float InitState::starLoader() {
  initStarLists();
  return 2;
}

float InitState::backgroundLoader() {
  if (!headless && !loadBackgroundObjects()) exit(EXIT_MALFORMED_DATA);
  return 2;
}

float InitState::systexLoader() {
  if (!headless)
    system_texture::load();
  return 2;
}

float InitState::initFontLoader() {
  float mult = (preliminaryRunMode? 2.0f : min(vheight,1.0f));
  float size = conf["conf"]["hud"]["font_size"];
  new (sysfont)         Font("fonts/westm",   size*mult, false);
  new (sysfontStipple)  Font("fonts/westm",   size*mult, true );
  new (smallFont)       Font("fonts/unifont", size*mult/1.5f, false);
  new (smallFontStipple)Font("fonts/unifont", size*mult/1.5f, true );
  return 2;
}

//Delays for 500 ms to wait for keystrokes
float InitState::keyboardDelay() {
  if (preliminaryRunMode) return 2; //Don't wait

  static Uint32 start = SDL_GetTicks();
  Uint32 end = SDL_GetTicks();
  return (end-start)/512.0f;
}
<commit_msg>Always use light-blue progress bar when loading prelim run mode.<commit_after>/**
 * @file
 * @author Jason Lingle
 * @brief Implementation of src/core/init_state.hxx
 */

#include <iostream>
#include <typeinfo>
#include <ctime>
#include <new>
#include <algorithm>

#include <GL/gl.h>
#include <SDL.h>

#include <tcl.h>

#include "init_state.hxx"
#include "src/abendstern.hxx"
#include "src/globals.hxx"
#include "src/graphics/imgload.hxx"
#include "src/test_state.hxx"
#include "src/fasttrig.hxx"
#include "src/background/background_object.hxx"
#include "src/background/star_field.hxx"
#include "src/background/explosion_pool.hxx"
#include "src/ship/sys/system_textures.hxx"
#include "src/graphics/vec.hxx"
#include "src/graphics/mat.hxx"
#include "src/graphics/matops.hxx"
#include "src/graphics/shader.hxx"
#include "src/graphics/cmn_shaders.hxx"
#include "src/graphics/glhelp.hxx"
#include "src/graphics/gl32emu.hxx"
#include "src/graphics/font.hxx"
#include "src/graphics/asgi.hxx"
#include "src/audio/audio.hxx"
#include "src/secondary/namegen.hxx"
#include "src/tcl_iface/bridge.hxx"
#include "src/exit_conditions.hxx"

using namespace std;

#if defined(AB_OPENGL_14)
#define LOGO "images/a14.png"
#elif defined(AB_OPENGL_21)
#define LOGO "images/a21.png"
#else
#define LOGO "images/a.png"
#endif

#define PRELIM_LOGO "images/a.png"

//For LSD-mode Easter Egg
static bool hasPressedL=false, hasPressedS=false, hasPressedD=false;

InitState::InitState() {
  currStep = 0;
  currStepProgress = 0;

  static float (*const stepsToLoad[])() = {
    &InitState::miscLoader,
    &InitState::initFontLoader,
    &InitState::systexLoader,
    &InitState::starLoader,
    &InitState::backgroundLoader,
    &InitState::keyboardDelay,
  };
  steps = stepsToLoad;
  numSteps = lenof(stepsToLoad);

  hasPainted=headless;
  if (!headless) {
    if (!preliminaryRunMode)
      SDL_ShowCursor(SDL_DISABLE);
    glGenTextures(1, &logo);
    vao = newVAO();
    glBindVertexArray(vao);
    vbo = newVBO();
    const char* error=loadImage(preliminaryRunMode? PRELIM_LOGO : LOGO, logo);
    if (error) {
      cerr << error << endl;
      exit(EXIT_MALFORMED_DATA);
    }
    //We can't set the buffer up yet, because vheight
    //has not yet been calculated.
  }
}

InitState::~InitState() {
  if (!headless) {
    glDeleteTextures(1, &logo);
    glDeleteBuffers(1, &vbo);
    glDeleteVertexArrays(1, &vao);
  }
}

GameState* InitState::update(float) {
  if (!hasPainted && !headless) return NULL;

  if (currStep < numSteps) {
    currStepProgress = steps[currStep]();
    if (currStepProgress > 1.0f) {
      currStepProgress = 0;
      ++currStep;
    }
  } else {
    if (hasPressedL && hasPressedS && hasPressedD) {
      enableLSDMode();
      shader::textureReplace.unload();
      shader::basic.unload();
    }

    //Start the root interpreter
    Tcl_Interp* root=newInterpreter(false);
    if (TCL_ERROR == Tcl_EvalFile(root, "tcl/autoexec.tcl")) {
      cerr << "FATAL: Autoexec did not run successfully: " << Tcl_GetStringResult(root) << endl;
      Tcl_Obj* options=Tcl_GetReturnOptions(root, TCL_ERROR);
      Tcl_Obj* key=Tcl_NewStringObj("-errorinfo", -1);
      Tcl_Obj* stackTrace;
      Tcl_IncrRefCount(key);
      Tcl_DictObjGet(NULL, options, key, &stackTrace);
      Tcl_DecrRefCount(key);
      cerr << "Stack trace:\n" << Tcl_GetStringFromObj(stackTrace, NULL) << endl;
      exit(EXIT_SCRIPTING_BUG);
    }
    if (this == state) {
      cerr << "FATAL: Autoexec did not change GameState" << endl;
      exit(EXIT_SCRIPTING_BUG);
    }
    if (!headless) {
      SDL_EnableUNICODE(1);
      SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
      //Tcl is taking over in a somewhat rude way, so
      //handle as gracefully as possible
      state->configureGL();
    }
  }

  return NULL;
}

void InitState::draw() {
  hasPainted=true;

  const shader::textureReplaceV quad[4] = {
      { {{0.5f-vheight/2,0      ,0,1}}, {{0,1}} },
      { {{0.5f+vheight/2,0      ,0,1}}, {{1,1}} },
      { {{0.5f-vheight/2,vheight,0,1}}, {{0,0}} },
      { {{0.5f+vheight/2,vheight,0,1}}, {{1,0}} },
  };

  shader::textureReplaceU uni;
  uni.colourMap=0;

  glBindVertexArray(vao);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
  shader::textureReplace->setupVBO();
  glBindTexture(GL_TEXTURE_2D, logo);
  shader::textureReplace->activate(&uni);
  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

  static const float progressH = 0.02f;
  static const float progressW = 0.3f;
  float currProgress = currStep/(float)numSteps + currStepProgress/numSteps;
  float baseX = 0.5f - progressW/2;
  if (!preliminaryRunMode) {
    #if defined(AB_OPENGL_14)
    asgi::colour(1.0f, 0.4f, 0.2f, 0.75f);
    #elif defined(AB_OPENGL_21)
    asgi::colour(0.2f, 1.0f, 0.4f, 0.75f);
    #else
    asgi::colour(0.2f, 0.3f, 0.9f, 0.75f);
    #endif
  } else {
    asgi::colour(0.2f, 0.3f, 0.9f, 0.75f);
  }
  asgi::begin(asgi::Quads);
  asgi::vertex(baseX, 4*progressH);
  asgi::vertex(baseX, 5*progressH);
  asgi::vertex(baseX + currProgress*progressW, 5*progressH);
  asgi::vertex(baseX + currProgress*progressW, 4*progressH);
  asgi::end();
  asgi::begin(asgi::Quads);
  asgi::vertex(baseX, 2.75f*progressH);
  asgi::vertex(baseX, 3.75f*progressH);
  asgi::vertex(baseX + currStepProgress*progressW, 3.75*progressH);
  asgi::vertex(baseX + currStepProgress*progressW, 2.75*progressH);
  asgi::end();
}

void InitState::keyboard(SDL_KeyboardEvent* e) {
  if (e->keysym.sym == SDLK_l)
    hasPressedL = true;
  else if (e->keysym.sym == SDLK_s)
    hasPressedS = true;
  else if (e->keysym.sym == SDLK_d)
    hasPressedD = true;
}

float InitState::miscLoader() {
  initTable(); //Trig tables
  sparkCountMultiplier=1;
  if (conf["conf"]["audio_enabled"]) audio::init();
  prepareTclBridge();
  namegenLoad();
  return 2;
}

float InitState::starLoader() {
  initStarLists();
  return 2;
}

float InitState::backgroundLoader() {
  if (!headless && !loadBackgroundObjects()) exit(EXIT_MALFORMED_DATA);
  return 2;
}

float InitState::systexLoader() {
  if (!headless)
    system_texture::load();
  return 2;
}

float InitState::initFontLoader() {
  float mult = (preliminaryRunMode? 2.0f : min(vheight,1.0f));
  float size = conf["conf"]["hud"]["font_size"];
  new (sysfont)         Font("fonts/westm",   size*mult, false);
  new (sysfontStipple)  Font("fonts/westm",   size*mult, true );
  new (smallFont)       Font("fonts/unifont", size*mult/1.5f, false);
  new (smallFontStipple)Font("fonts/unifont", size*mult/1.5f, true );
  return 2;
}

//Delays for 500 ms to wait for keystrokes
float InitState::keyboardDelay() {
  if (preliminaryRunMode) return 2; //Don't wait

  static Uint32 start = SDL_GetTicks();
  Uint32 end = SDL_GetTicks();
  return (end-start)/512.0f;
}
<|endoftext|>


<commit_before>#include "store.h"
#include <map>
#include <iostream>
#include <fstream>

using namespace std;

class Store_map : Store
{
public:
	Store_map();
	~Store_map();

	// Open and close store
	void open(string filename){
		ifstream ifs;
		string buff_word;
		int buff_n;
		ifs.open(filename);

		if (!ifs.is_open() || !ifs.good()){
			cerr << "ERROR : couldn't load file " << filename << endl;
		}
		else{
			cin >> tot;
			while (cin >> buff_word){
				cin >> buff_n;
				hits.insert(pair<string, int>(buff_word, buff_n));
			}

		}
		ifs.close();
	}

	void close(string filename){
		ofstream ofs;

		if (!ofs.is_open() || !ofs.good()){
			cerr << "ERROR : couldn't open file " << filename << endl;
		}
		else{
			for (pair<string, int> p : hits){
				cout << p.first << " " << p.second << endl;
			}
		}
		ofs.close();
	}

	// Check if store is initialized (e.g. table was created, etc.) and initializes it
	bool is_init(){
		return true;
	}

	void init(){}

	// Check if word exists and insert it
	bool exists(string word){
		return hits.find(word) != hits.end();
	}

	void create(string word, int nb){
		hits.insert(pair<string, int>(word, nb));
		tot += nb;
	}

	// Access or modify hits
	int get_hits(string word){
		return hits[word];
	}
	void set_hits(string word, int nb){
		tot += nb - hits[word];
		hits[word] = nb;

	}

	// Access proba
	double get_proba(string word){
		return ((float)hits[word])/((double)tot);
	}

private:
	int tot;
	map<string, int> hits;
};
<commit_msg>remove useless file<commit_after><|endoftext|>


<commit_before>/* This file is part of the UniSet project
 * Copyright (c) 2002 Free Software Foundation, Inc.
 * Copyright (c) 2002 Pavel Vainerman
 *
 * 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.
 */
// --------------------------------------------------------------------------
/*! \file
 *  \author Pavel Vainerman
*/
// --------------------------------------------------------------------------
#include <sstream>
#include <cstdio>
#include "UniSetTypes.h"
#include "SQLiteInterface.h"
// --------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// --------------------------------------------------------------------------

SQLiteInterface::SQLiteInterface():
db(0),
lastQ(""),
lastE(""),
queryok(false),
connected(false),
opTimeout(300),
opCheckPause(50)
{
}

SQLiteInterface::~SQLiteInterface()
{
	close();
	delete db;
}

// -----------------------------------------------------------------------------------------
bool SQLiteInterface::ping()
{
	return db && ( sqlite3_db_status(db,0,NULL,NULL,0) == SQLITE_OK );
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::connect( const string& dbfile, bool create )
{
	// т.к. sqlite3 по умолчанию, создаёт файл при открытии, то проверим "сами"
//	if( !create && !UniSetTypes::file_exist(dbfile) )
//		return false;

	int flags = create ? 0 : SQLITE_OPEN_READWRITE;

	int rc = sqlite3_open_v2(dbfile.c_str(), &db, flags, NULL);

	if( rc != SQLITE_OK )
	{
		// cerr << "SQLiteInterface::connect): rc=" << rc << " error: " << sqlite3_errmsg(db) << endl;
		lastE = "open '" + dbfile + "' error: " + string(sqlite3_errmsg(db));
		sqlite3_close(db);
		db = 0;
		connected = false;
		return false;
	}

	setOperationTimeout(opTimeout);
	connected = true;
	return true;
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::close()
{
	if( db )
	{
		sqlite3_close(db);
		db = 0;
	}

	return true;
}
// -----------------------------------------------------------------------------------------
void SQLiteInterface::setOperationTimeout( timeout_t msec )
{
	opTimeout = msec;
	if( db )
		sqlite3_busy_timeout(db,opTimeout);
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::insert( const string& q )
{
	if( !db )
		return false;

	// char* errmsg;
	sqlite3_stmt* pStmt;

	// Компилируем SQL запрос
	if( sqlite3_prepare(db, q.c_str(), -1, &pStmt, NULL) != SQLITE_OK )
	{
		queryok = false;
		return false;
	}

	int rc = sqlite3_step(pStmt);

	if( !checkResult(rc) && !wait(pStmt, SQLITE_DONE) )
	{
		sqlite3_finalize(pStmt);
		queryok = false;
		return false;
	}

	sqlite3_finalize(pStmt);
	queryok=true;
	return true;
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::checkResult( int rc )
{
	if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED || rc==SQLITE_INTERRUPT || rc==SQLITE_IOERR )
		return false;

	return true;
}
// -----------------------------------------------------------------------------------------
SQLiteResult SQLiteInterface::query( const string& q )
{
	if( !db )
		return SQLiteResult();

	// char* errmsg = 0;
	sqlite3_stmt* pStmt;

	// Компилируем SQL запрос
	sqlite3_prepare(db, q.c_str(), -1, &pStmt, NULL);
	int rc = sqlite3_step(pStmt);
	if( !checkResult(rc) && !wait(pStmt, SQLITE_ROW) )
	{
		sqlite3_finalize(pStmt);
		queryok = false;
		return SQLiteResult();
	}

	lastQ = q;
	queryok=true;
	return SQLiteResult(pStmt,true);
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::wait( sqlite3_stmt* stmt, int result )
{
	PassiveTimer ptTimeout(opTimeout);
	while( !ptTimeout.checkTime() )
	{
		sqlite3_reset(stmt);
		int rc = sqlite3_step(stmt);
		if(  rc == result || rc == SQLITE_DONE )
			return true;

		msleep(opCheckPause);
	}

	return false;
}
// -----------------------------------------------------------------------------------------
string SQLiteInterface::error()
{
	if( db )
		lastE = sqlite3_errmsg(db);

	return lastE;
}
// -----------------------------------------------------------------------------------------
const string SQLiteInterface::lastQuery()
{
	return lastQ;
}
// -----------------------------------------------------------------------------------------
int SQLiteInterface::insert_id()
{
	if( !db )
		return 0;

	return sqlite3_last_insert_rowid(db);
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::isConnection()
{
	return connected;
}
// -----------------------------------------------------------------------------------------
int num_cols( SQLiteResult::iterator& it )
{
	return it->size();
}
// -----------------------------------------------------------------------------------------
int as_int( SQLiteResult::iterator& it, int col )
{
//	if( col<0 || col >it->size() )
//		return 0;
	return uni_atoi( (*it)[col] );
}
// -----------------------------------------------------------------------------------------
double as_double( SQLiteResult::iterator& it, int col )
{
	return atof( ((*it)[col]).c_str() );
}
// -----------------------------------------------------------------------------------------
string as_string( SQLiteResult::iterator& it, int col )
{
	return ((*it)[col]);
}
// -----------------------------------------------------------------------------------------
int as_int( SQLiteResult::COL::iterator& it )
{
	return uni_atoi( (*it) );
}
// -----------------------------------------------------------------------------------------
double as_double( SQLiteResult::COL::iterator& it )
{
	return atof( (*it).c_str() );
}
// -----------------------------------------------------------------------------------------
std::string as_string( SQLiteResult::COL::iterator& it )
{
	return (*it);
}
// -----------------------------------------------------------------------------------------
#if 0
SQLiteResult::COL get_col( SQLiteResult::ROW::iterator& it )
{
	return (*it);
}
#endif
// -----------------------------------------------------------------------------------------
SQLiteResult::~SQLiteResult()
{

}
// -----------------------------------------------------------------------------------------
SQLiteResult::SQLiteResult( sqlite3_stmt* s, bool finalize )
{
	do
	{
		int n = sqlite3_data_count(s);
		COL	c;

		for( int i=0; i<n; i++ )
		{
			char* p = (char*)sqlite3_column_text(s,i);
			if( p )
				c.push_back(p);
			else
				c.push_back("");
		}
		res.push_back(c);
	}
	while( sqlite3_step(s) == SQLITE_ROW );

	if( finalize )
		sqlite3_finalize(s);
}
// -----------------------------------------------------------------------------------------
<commit_msg>(SQLite): добавил принудительное выставление флагов при создании соединения с БД( вместо умолчательное)<commit_after>/* This file is part of the UniSet project
 * Copyright (c) 2002 Free Software Foundation, Inc.
 * Copyright (c) 2002 Pavel Vainerman
 *
 * 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.
 */
// --------------------------------------------------------------------------
/*! \file
 *  \author Pavel Vainerman
*/
// --------------------------------------------------------------------------
#include <sstream>
#include <cstdio>
#include "UniSetTypes.h"
#include "SQLiteInterface.h"
// --------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// --------------------------------------------------------------------------

SQLiteInterface::SQLiteInterface():
db(0),
lastQ(""),
lastE(""),
queryok(false),
connected(false),
opTimeout(300),
opCheckPause(50)
{
}

SQLiteInterface::~SQLiteInterface()
{
	close();
	delete db;
}

// -----------------------------------------------------------------------------------------
bool SQLiteInterface::ping()
{
	return db && ( sqlite3_db_status(db,0,NULL,NULL,0) == SQLITE_OK );
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::connect( const string& dbfile, bool create )
{
	// т.к. sqlite3 по умолчанию, создаёт файл при открытии, то проверим "сами"
//	if( !create && !UniSetTypes::file_exist(dbfile) )
//		return false;

	int flags = SQLITE_OPEN_READWRITE;
	if( create )
		flags |= SQLITE_OPEN_CREATE;

	int rc = sqlite3_open_v2(dbfile.c_str(), &db, flags, NULL);

	if( rc != SQLITE_OK )
	{
		// cerr << "SQLiteInterface::connect): rc=" << rc << " error: " << sqlite3_errmsg(db) << endl;
		lastE = "open '" + dbfile + "' error: " + string(sqlite3_errmsg(db));
		sqlite3_close(db);
		db = 0;
		connected = false;
		return false;
	}

	setOperationTimeout(opTimeout);
	connected = true;
	return true;
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::close()
{
	if( db )
	{
		sqlite3_close(db);
		db = 0;
	}

	return true;
}
// -----------------------------------------------------------------------------------------
void SQLiteInterface::setOperationTimeout( timeout_t msec )
{
	opTimeout = msec;
	if( db )
		sqlite3_busy_timeout(db,opTimeout);
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::insert( const string& q )
{
	if( !db )
		return false;

	// char* errmsg;
	sqlite3_stmt* pStmt;

	// Компилируем SQL запрос
	if( sqlite3_prepare(db, q.c_str(), -1, &pStmt, NULL) != SQLITE_OK )
	{
		queryok = false;
		return false;
	}

	int rc = sqlite3_step(pStmt);

	if( !checkResult(rc) && !wait(pStmt, SQLITE_DONE) )
	{
		sqlite3_finalize(pStmt);
		queryok = false;
		return false;
	}

	sqlite3_finalize(pStmt);
	queryok=true;
	return true;
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::checkResult( int rc )
{
	if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED || rc==SQLITE_INTERRUPT || rc==SQLITE_IOERR ) // || rc==SQLITE_NOMEM || rc==SQLITE_FULL )
		return false;

	return true;
}
// -----------------------------------------------------------------------------------------
SQLiteResult SQLiteInterface::query( const string& q )
{
	if( !db )
		return SQLiteResult();

	// char* errmsg = 0;
	sqlite3_stmt* pStmt;

	// Компилируем SQL запрос
	sqlite3_prepare(db, q.c_str(), -1, &pStmt, NULL);
	int rc = sqlite3_step(pStmt);
	if( !checkResult(rc) && !wait(pStmt, SQLITE_ROW) )
	{
		sqlite3_finalize(pStmt);
		queryok = false;
		return SQLiteResult();
	}

	lastQ = q;
	queryok=true;
	return SQLiteResult(pStmt,true);
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::wait( sqlite3_stmt* stmt, int result )
{
	PassiveTimer ptTimeout(opTimeout);
	while( !ptTimeout.checkTime() )
	{
		sqlite3_reset(stmt);
		int rc = sqlite3_step(stmt);
		if(  rc == result || rc == SQLITE_DONE )
			return true;

		msleep(opCheckPause);
	}

	return false;
}
// -----------------------------------------------------------------------------------------
string SQLiteInterface::error()
{
	if( db )
		lastE = sqlite3_errmsg(db);

	return lastE;
}
// -----------------------------------------------------------------------------------------
const string SQLiteInterface::lastQuery()
{
	return lastQ;
}
// -----------------------------------------------------------------------------------------
int SQLiteInterface::insert_id()
{
	if( !db )
		return 0;

	return sqlite3_last_insert_rowid(db);
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::isConnection()
{
	return connected;
}
// -----------------------------------------------------------------------------------------
int num_cols( SQLiteResult::iterator& it )
{
	return it->size();
}
// -----------------------------------------------------------------------------------------
int as_int( SQLiteResult::iterator& it, int col )
{
//	if( col<0 || col >it->size() )
//		return 0;
	return uni_atoi( (*it)[col] );
}
// -----------------------------------------------------------------------------------------
double as_double( SQLiteResult::iterator& it, int col )
{
	return atof( ((*it)[col]).c_str() );
}
// -----------------------------------------------------------------------------------------
string as_string( SQLiteResult::iterator& it, int col )
{
	return ((*it)[col]);
}
// -----------------------------------------------------------------------------------------
int as_int( SQLiteResult::COL::iterator& it )
{
	return uni_atoi( (*it) );
}
// -----------------------------------------------------------------------------------------
double as_double( SQLiteResult::COL::iterator& it )
{
	return atof( (*it).c_str() );
}
// -----------------------------------------------------------------------------------------
std::string as_string( SQLiteResult::COL::iterator& it )
{
	return (*it);
}
// -----------------------------------------------------------------------------------------
#if 0
SQLiteResult::COL get_col( SQLiteResult::ROW::iterator& it )
{
	return (*it);
}
#endif
// -----------------------------------------------------------------------------------------
SQLiteResult::~SQLiteResult()
{

}
// -----------------------------------------------------------------------------------------
SQLiteResult::SQLiteResult( sqlite3_stmt* s, bool finalize )
{
	do
	{
		int n = sqlite3_data_count(s);
		COL	c;

		for( int i=0; i<n; i++ )
		{
			char* p = (char*)sqlite3_column_text(s,i);
			if( p )
				c.push_back(p);
			else
				c.push_back("");
		}
		res.push_back(c);
	}
	while( sqlite3_step(s) == SQLITE_ROW );

	if( finalize )
		sqlite3_finalize(s);
}
// -----------------------------------------------------------------------------------------
<|endoftext|>


<commit_before>#include "window.h"
#include "control.h"
#include "logger.h"
#include "string_utils.h"

#include <FL/fl_ask.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Input_Choice.H>

#include <cassert>
#include <algorithm>
#include <vector>

void Vindow::FileNew(Fl_Widget*, void*)
{}

void Vindow::FileOpen(Fl_Widget*, void*)
{}

void Vindow::FileSave(Fl_Widget*, void* p)
{
    extern void save_model(std::shared_ptr<Model>, std::wstring);
    auto* me = (Vindow*)p;

    std::wstring testPath(L"test.txt");
    save_model(me->model_, testPath);
}

void Vindow::FileSaveAs(Fl_Widget*, void*)
{}

void Vindow::FileReload(Fl_Widget*, void*)
{}

void Vindow::FileExit(Fl_Widget*, void*)
{
    extern bool is_any_model_dirty();
    if(is_any_model_dirty())
    {
        int which = fl_choice("There are unsaved documents.\nAre you sure you want to exit?\n(Hint: use Vindow/Close to close just one window)", "&No", nullptr, "&Yes");
        if(which != 2) return;
    }
    exit(0);
}

void Vindow::EditUndo(Fl_Widget*, void*)
{}

void Vindow::EditCut(Fl_Widget*, void*)
{}

void Vindow::EditCopy(Fl_Widget*, void*)
{}

void Vindow::EditPaste(Fl_Widget*, void*)
{}

void Vindow::EditInsertRest(Fl_Widget*, void* p)
{
    LOGGER(l);
    auto me = (Vindow*)p;
    assert(me->editor_);
    Control ctrl(me->model_, me);
    if(me->layout_ == Vindow::Layout::OUTPUT) {
#if 1
        l(L"using text editor, this should not be called\n");
#else
        auto pos = me->model_->output.begin();
        std::advance(pos, me->editor_->mx());
        ctrl.InsertColumn(me->active_, pos, L'.');
        assert(me->editor_);
        me->editor_->Update(me->model_->whats.size());
#endif
    } else if(me->layout_ == Vindow::Layout::WHAT) {
        auto found = std::find_if(me->model_->whats.begin(), me->model_->whats.end(), [me](WhatEntry& what) -> bool {
                    return what.name == me->active_;
                });
        if(found == me->model_->whats.end()) {
            l(L"%ls not found\n", me->active_.c_str());
            return;
        }
        auto pos = found->columns.begin();
        std::advance(pos, me->editor_->mx());
        ctrl.InsertColumn(me->active_, pos, L'.');
        assert(me->editor_);
        me->editor_->Update(me->model_->whos.size());
    }
}

void Vindow::EditInsertBlank(Fl_Widget*, void* p)
{
    LOGGER(l);
    auto me = (Vindow*)p;
    assert(me->editor_);
    Control ctrl(me->model_, me);
    if(me->layout_ == Vindow::Layout::OUTPUT) {
#if 1
        l(L"using text editor, should not be called\n");
#else
        auto pos = me->model_->output.begin();
        std::advance(pos, me->editor_->mx());
        ctrl.InsertColumn(me->active_, pos, ' ');
        assert(me->editor_);
        me->editor_->Update(me->model_->whats.size());
#endif
    } else if(me->layout_ == Vindow::Layout::WHAT) {
        auto found = std::find_if(me->model_->whats.begin(), me->model_->whats.end(), [me](WhatEntry& what) -> bool {
                    return what.name == me->active_;
                });
        if(found == me->model_->whats.end()) {
            l(L"%s not found\n", me->active_);
            return;
        }
        auto pos = found->columns.begin();
        std::advance(pos, me->editor_->mx());
        ctrl.InsertColumn(me->active_, pos, ' ');
        assert(me->editor_);
        me->editor_->Update(me->model_->whos.size());
    }
}

// if selection, goto sel
// if cursorx == 0, return
// if previous char == ' ', move cursor left, return
// if previous char != ' ', replace with '.' and move cursor left, return
// sel: for each cell
//          if previous char == ' ', continue
//          if previous char != ' ', replace with '.', continue
void Vindow::EditClearColumns(Fl_Widget*, void* p)
{
    LOGGER(l);
    auto* me = (Vindow*)p;
    if(!me->editor_) return;

    if(me->layout_ == Vindow::Layout::WHO) {
        l(L"Nothing to do in WHO layout\n");
        return;
    }

    if(!me->editor_) {
        l(L"missing editor!\n");
        return;
    }
    if(me->editor_->mx() == 0) {
        l(L"no character to the left\n");
        return;
    }

    Control ctrl(me->model_, me);
    ctrl.BlankCell(me->active_, me->editor_->mx() - 1, me->editor_->my());

    me->editor_->SetCursor(me->editor_->my(), me->editor_->mx() - 1);
    me->editor_->Update();
}

void Vindow::EditDeleteColumns(Fl_Widget*, void*)
{}

void Vindow::EditAddWhat(Fl_Widget*, void*)
{}

void Vindow::EditAddWho(Fl_Widget*, void*)
{}

void Vindow::EditDeleteSection(Fl_Widget*, void*)
{}

void Vindow::WindowNew(Fl_Widget*, void* p)
{
    extern void create_window(std::shared_ptr<Model>);
    Vindow* me = (Vindow*)p;
    create_window(me->model_);
}

void Vindow::WindowClose(Fl_Widget*, void* p)
{
    extern void destroy_window(Vindow*);
    Vindow* me = (Vindow*)p;
    if(me->model_->dirty
            && me->model_->views.size() == 1)
    {
        int which = fl_choice("There are unsaved changes in the document.\nClosing this window will discard all changes.\nDo you want to close this document?", "&No", nullptr, "&Yes");
        if(which != 2) return;
    }
    return destroy_window(me);
}

void Vindow::WindowCloseAll(Fl_Widget*, void* p)
{
    extern void destroy_window(Vindow*);
    Vindow* me = (Vindow*)p;
    if(me->model_->dirty)
    {
        int which = fl_choice("There are unsaved changes in the document.\nDo you want to close this document, discarding changes?", "&No", nullptr, "&Yes");
        if(which != 2) return;
    }
    std::vector<View*> toDestroy;
    std::copy_if(me->model_->views.begin(), me->model_->views.end(), std::back_inserter(toDestroy), [me](View* view) -> bool {
                auto* w = dynamic_cast<Vindow*>(view);
                if(w == me) return false;
                return w != nullptr;
            });
    for(auto* view : toDestroy)
    {
        auto* w = dynamic_cast<Vindow*>(view);
        if(w) destroy_window(w);
    }
    return destroy_window(me);
}

void Vindow::HelpAbout(Fl_Widget*, void*)
{
    fl_alert("JakBeat GUI\nCopyright (c) 2015-2017 Vlad Meșco\nAvailable under the 2-Clause BSD License");
}

void Vindow::WhatClicked(Fl_Widget* w, void* p)
{
    Vindow* me = (Vindow*)p;
    const char* label = w->label();
    me->SetLayout(Layout::WHAT, MB2W(label));
    me->redraw();
}

void Vindow::WhoClicked(Fl_Widget* w, void* p)
{
    Vindow* me = (Vindow*)p;
    const char* label = w->label();
    me->SetLayout(Layout::WHO, MB2W(label));
    me->redraw();
}

void Vindow::OutputClicked(Fl_Widget* w, void* p)
{
    Vindow* me = (Vindow*)p;
    me->SetLayout(Layout::OUTPUT);
    me->redraw();
}

void Vindow::WindowCallback(Fl_Widget* w, void* p)
{
    WindowClose(w, p);
}

void Vindow::WhoNameChanged(Fl_Widget* w, void* p)
{
    auto* inp = (Fl_Input*)w;
    auto* me = (Vindow*)p;

    std::wstring newName = MB2W(inp->value());
    std::wstring oldName = me->active_;

    if(std::any_of(me->model_->whos.begin(), me->model_->whos.end(), [newName](WhoEntry const& e) -> bool {
                    return e.name == newName;
                })
            || newName.empty())
    {
        fl_alert("Name needs to be unique and not null");
        inp->value(W2MB(oldName).get());
        // Fl::focus(inp); // doesn't work because e.g. the tab key is
                           // handled later...
        return;
    }

    Control ctrl(me->model_, me);
    ctrl.SetWhosName(oldName, newName);
}

void Vindow::WhatNameChanged(Fl_Widget* w, void* p)
{
    auto* inp = (Fl_Input*)w;
    auto* me = (Vindow*)p;

    std::wstring newName = MB2W(inp->value());
    std::wstring oldName = me->active_;

    if(std::any_of(me->model_->whats.begin(), me->model_->whats.end(), [newName](WhatEntry const& e) -> bool {
                    return e.name == newName;
                })
            || newName.empty()
            || newName == L"OUTPUT")
    {
        fl_alert("Name needs to be unique and not null");
        inp->value(W2MB(oldName).get());
        // Fl::focus(inp); // doesn't work because e.g. the tab key is
                           // handled later...
        return;
    }

    Control ctrl(me->model_, me);
    ctrl.SetWhatsName(oldName, newName);
}

void Vindow::WhatBpmChanged(Fl_Widget* w, void* p)
{
    auto* inp = dynamic_cast<Fl_Input*>(w);
    auto* me = (Vindow*)p;

    auto&& what = me->active_;
    auto bpm = MB2W(inp->value());

    Control ctrl(me->model_, me);
    ctrl.SetWhatsBpm(what, bpm);
}

void Vindow::SchemaChanged(Fl_Widget* w, void* p)
{
    auto* inp = (Fl_Input_Choice*)w;
    auto* me = (Vindow*)p;

    auto&& who = me->active_;
    int idx = inp->menubutton()->value();
    assert(idx >= 0 && idx < me->drumSchemas_.size());
    Schema const* schema = &me->drumSchemas_[idx];

    Control ctrl(me->model_, me);
    ctrl.SetWhosSchema(who, schema);
}

void Vindow::ParamChanged(Fl_Widget* w, void* p)
{
    auto* inp = dynamic_cast<Fl_Input*>(w);
    auto* me = (Vindow*)p;

    auto&& who = me->active_;
    std::wstring param = MB2W(inp->label());
    std::wstring value = MB2W(inp->value());

    Control ctrl(me->model_, me);
    ctrl.SetWhosParam(who, param, value);
}

void Vindow::OutputChanged(int pos, int inserted, int deleted, int restyled, const char* deletedText, void* cbArg)
{
    LOGGER(l);
    auto* me = (Vindow*)cbArg;
    if(me->blockBufferChanged_) {
        l(L"refreshed, not triggering event\n");
        return;
    }
    l(L"pos=%d inserted=%d deleted=%d restyled=%d\n", pos, inserted, deleted, restyled);
    if(deletedText)
        l(L"deletedText=%ls\n", MB2W(deletedText).c_str());
    auto* ss = me->buffer_->address(pos);
    auto text = MB2W(ss, inserted);
    l(L"text=%ls\n", text.c_str());
    Control ctrl(me->model_, me);
    if(deleted) {
        ctrl.DeleteText(pos, deleted);
    }
    if(inserted) {
        ctrl.InsertText(pos, text);
    }
}
<commit_msg>prevent the creation of reserved sections<commit_after>#include "window.h"
#include "control.h"
#include "logger.h"
#include "string_utils.h"

#include <FL/fl_ask.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Input_Choice.H>

#include <cassert>
#include <algorithm>
#include <vector>

void Vindow::FileNew(Fl_Widget*, void*)
{}

void Vindow::FileOpen(Fl_Widget*, void*)
{}

void Vindow::FileSave(Fl_Widget*, void* p)
{
    extern void save_model(std::shared_ptr<Model>, std::wstring);
    auto* me = (Vindow*)p;

    std::wstring testPath(L"test.txt");
    save_model(me->model_, testPath);
}

void Vindow::FileSaveAs(Fl_Widget*, void*)
{}

void Vindow::FileReload(Fl_Widget*, void*)
{}

void Vindow::FileExit(Fl_Widget*, void*)
{
    extern bool is_any_model_dirty();
    if(is_any_model_dirty())
    {
        int which = fl_choice("There are unsaved documents.\nAre you sure you want to exit?\n(Hint: use Vindow/Close to close just one window)", "&No", nullptr, "&Yes");
        if(which != 2) return;
    }
    exit(0);
}

void Vindow::EditUndo(Fl_Widget*, void*)
{}

void Vindow::EditCut(Fl_Widget*, void*)
{}

void Vindow::EditCopy(Fl_Widget*, void*)
{}

void Vindow::EditPaste(Fl_Widget*, void*)
{}

void Vindow::EditInsertRest(Fl_Widget*, void* p)
{
    LOGGER(l);
    auto me = (Vindow*)p;
    assert(me->editor_);
    Control ctrl(me->model_, me);
    if(me->layout_ == Vindow::Layout::OUTPUT) {
#if 1
        l(L"using text editor, this should not be called\n");
#else
        auto pos = me->model_->output.begin();
        std::advance(pos, me->editor_->mx());
        ctrl.InsertColumn(me->active_, pos, L'.');
        assert(me->editor_);
        me->editor_->Update(me->model_->whats.size());
#endif
    } else if(me->layout_ == Vindow::Layout::WHAT) {
        auto found = std::find_if(me->model_->whats.begin(), me->model_->whats.end(), [me](WhatEntry& what) -> bool {
                    return what.name == me->active_;
                });
        if(found == me->model_->whats.end()) {
            l(L"%ls not found\n", me->active_.c_str());
            return;
        }
        auto pos = found->columns.begin();
        std::advance(pos, me->editor_->mx());
        ctrl.InsertColumn(me->active_, pos, L'.');
        assert(me->editor_);
        me->editor_->Update(me->model_->whos.size());
    }
}

void Vindow::EditInsertBlank(Fl_Widget*, void* p)
{
    LOGGER(l);
    auto me = (Vindow*)p;
    assert(me->editor_);
    Control ctrl(me->model_, me);
    if(me->layout_ == Vindow::Layout::OUTPUT) {
#if 1
        l(L"using text editor, should not be called\n");
#else
        auto pos = me->model_->output.begin();
        std::advance(pos, me->editor_->mx());
        ctrl.InsertColumn(me->active_, pos, ' ');
        assert(me->editor_);
        me->editor_->Update(me->model_->whats.size());
#endif
    } else if(me->layout_ == Vindow::Layout::WHAT) {
        auto found = std::find_if(me->model_->whats.begin(), me->model_->whats.end(), [me](WhatEntry& what) -> bool {
                    return what.name == me->active_;
                });
        if(found == me->model_->whats.end()) {
            l(L"%s not found\n", me->active_);
            return;
        }
        auto pos = found->columns.begin();
        std::advance(pos, me->editor_->mx());
        ctrl.InsertColumn(me->active_, pos, ' ');
        assert(me->editor_);
        me->editor_->Update(me->model_->whos.size());
    }
}

// if selection, goto sel
// if cursorx == 0, return
// if previous char == ' ', move cursor left, return
// if previous char != ' ', replace with '.' and move cursor left, return
// sel: for each cell
//          if previous char == ' ', continue
//          if previous char != ' ', replace with '.', continue
void Vindow::EditClearColumns(Fl_Widget*, void* p)
{
    LOGGER(l);
    auto* me = (Vindow*)p;
    if(!me->editor_) return;

    if(me->layout_ == Vindow::Layout::WHO) {
        l(L"Nothing to do in WHO layout\n");
        return;
    }

    if(!me->editor_) {
        l(L"missing editor!\n");
        return;
    }
    if(me->editor_->mx() == 0) {
        l(L"no character to the left\n");
        return;
    }

    Control ctrl(me->model_, me);
    ctrl.BlankCell(me->active_, me->editor_->mx() - 1, me->editor_->my());

    me->editor_->SetCursor(me->editor_->my(), me->editor_->mx() - 1);
    me->editor_->Update();
}

void Vindow::EditDeleteColumns(Fl_Widget*, void*)
{}

void Vindow::EditAddWhat(Fl_Widget*, void*)
{}

void Vindow::EditAddWho(Fl_Widget*, void*)
{}

void Vindow::EditDeleteSection(Fl_Widget*, void*)
{}

void Vindow::WindowNew(Fl_Widget*, void* p)
{
    extern void create_window(std::shared_ptr<Model>);
    Vindow* me = (Vindow*)p;
    create_window(me->model_);
}

void Vindow::WindowClose(Fl_Widget*, void* p)
{
    extern void destroy_window(Vindow*);
    Vindow* me = (Vindow*)p;
    if(me->model_->dirty
            && me->model_->views.size() == 1)
    {
        int which = fl_choice("There are unsaved changes in the document.\nClosing this window will discard all changes.\nDo you want to close this document?", "&No", nullptr, "&Yes");
        if(which != 2) return;
    }
    return destroy_window(me);
}

void Vindow::WindowCloseAll(Fl_Widget*, void* p)
{
    extern void destroy_window(Vindow*);
    Vindow* me = (Vindow*)p;
    if(me->model_->dirty)
    {
        int which = fl_choice("There are unsaved changes in the document.\nDo you want to close this document, discarding changes?", "&No", nullptr, "&Yes");
        if(which != 2) return;
    }
    std::vector<View*> toDestroy;
    std::copy_if(me->model_->views.begin(), me->model_->views.end(), std::back_inserter(toDestroy), [me](View* view) -> bool {
                auto* w = dynamic_cast<Vindow*>(view);
                if(w == me) return false;
                return w != nullptr;
            });
    for(auto* view : toDestroy)
    {
        auto* w = dynamic_cast<Vindow*>(view);
        if(w) destroy_window(w);
    }
    return destroy_window(me);
}

void Vindow::HelpAbout(Fl_Widget*, void*)
{
    fl_alert("JakBeat GUI\nCopyright (c) 2015-2017 Vlad Meșco\nAvailable under the 2-Clause BSD License");
}

void Vindow::WhatClicked(Fl_Widget* w, void* p)
{
    Vindow* me = (Vindow*)p;
    const char* label = w->label();
    me->SetLayout(Layout::WHAT, MB2W(label));
    me->redraw();
}

void Vindow::WhoClicked(Fl_Widget* w, void* p)
{
    Vindow* me = (Vindow*)p;
    const char* label = w->label();
    me->SetLayout(Layout::WHO, MB2W(label));
    me->redraw();
}

void Vindow::OutputClicked(Fl_Widget* w, void* p)
{
    Vindow* me = (Vindow*)p;
    me->SetLayout(Layout::OUTPUT);
    me->redraw();
}

void Vindow::WindowCallback(Fl_Widget* w, void* p)
{
    WindowClose(w, p);
}

void Vindow::WhoNameChanged(Fl_Widget* w, void* p)
{
    auto* inp = (Fl_Input*)w;
    auto* me = (Vindow*)p;

    std::wstring newName = MB2W(inp->value());
    std::wstring oldName = me->active_;

    if(std::any_of(me->model_->whos.begin(), me->model_->whos.end(), [newName](WhoEntry const& e) -> bool {
                    return e.name == newName;
                })
            || newName.empty())
    {
        fl_alert("Name needs to be unique and not null");
        inp->value(W2MB(oldName).get());
        // Fl::focus(inp); // doesn't work because e.g. the tab key is
                           // handled later...
        return;
    }

    Control ctrl(me->model_, me);
    ctrl.SetWhosName(oldName, newName);
}

void Vindow::WhatNameChanged(Fl_Widget* w, void* p)
{
    auto* inp = (Fl_Input*)w;
    auto* me = (Vindow*)p;

    std::wstring newName = MB2W(inp->value());
    std::wstring oldName = me->active_;

    if(std::any_of(me->model_->whats.begin(), me->model_->whats.end(), [newName](WhatEntry const& e) -> bool {
                    return e.name == newName;
                })
            || newName.empty()
            /* reserved */
            || newName == L"OUTPUT"
            || newName == L"Output"
            || newName == L"WHO"
            || newName == L"WHAT")
    {
        fl_alert("Name needs to be unique, not reserved, and not null");
        inp->value(W2MB(oldName).get());
        // Fl::focus(inp); // doesn't work because e.g. the tab key is
                           // handled later...
        return;
    }

    Control ctrl(me->model_, me);
    ctrl.SetWhatsName(oldName, newName);
}

void Vindow::WhatBpmChanged(Fl_Widget* w, void* p)
{
    auto* inp = dynamic_cast<Fl_Input*>(w);
    auto* me = (Vindow*)p;

    auto&& what = me->active_;
    auto bpm = MB2W(inp->value());

    Control ctrl(me->model_, me);
    ctrl.SetWhatsBpm(what, bpm);
}

void Vindow::SchemaChanged(Fl_Widget* w, void* p)
{
    auto* inp = (Fl_Input_Choice*)w;
    auto* me = (Vindow*)p;

    auto&& who = me->active_;
    int idx = inp->menubutton()->value();
    assert(idx >= 0 && idx < me->drumSchemas_.size());
    Schema const* schema = &me->drumSchemas_[idx];

    Control ctrl(me->model_, me);
    ctrl.SetWhosSchema(who, schema);
}

void Vindow::ParamChanged(Fl_Widget* w, void* p)
{
    auto* inp = dynamic_cast<Fl_Input*>(w);
    auto* me = (Vindow*)p;

    auto&& who = me->active_;
    std::wstring param = MB2W(inp->label());
    std::wstring value = MB2W(inp->value());

    Control ctrl(me->model_, me);
    ctrl.SetWhosParam(who, param, value);
}

void Vindow::OutputChanged(int pos, int inserted, int deleted, int restyled, const char* deletedText, void* cbArg)
{
    LOGGER(l);
    auto* me = (Vindow*)cbArg;
    if(me->blockBufferChanged_) {
        l(L"refreshed, not triggering event\n");
        return;
    }
    l(L"pos=%d inserted=%d deleted=%d restyled=%d\n", pos, inserted, deleted, restyled);
    if(deletedText)
        l(L"deletedText=%ls\n", MB2W(deletedText).c_str());
    auto* ss = me->buffer_->address(pos);
    auto text = MB2W(ss, inserted);
    l(L"text=%ls\n", text.c_str());
    Control ctrl(me->model_, me);
    if(deleted) {
        ctrl.DeleteText(pos, deleted);
    }
    if(inserted) {
        ctrl.InsertText(pos, text);
    }
}
<|endoftext|>


<commit_before>//
// Managed C++ wrapper class around the Hugs server API.
//
#using <mscorlib.dll>
extern "C" {
#include "prelude.h"
#include "storage.h"
#include "connect.h"
};
#include "prim.h"
#include "HugsServ.h"

#define ToCharString(str) \
  static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str).ToPointer())
#define FreeCharString(pstr) System::Runtime::InteropServices::Marshal::FreeHGlobal(pstr)

extern "C" {
extern char* lastError;
extern char* ClearError();
extern Void  setError  (char*);
extern Bool  safeEval  (Cell c);
extern Void  startEval (Void);
};

/* All server entry points set CStackBase for the benefit of the (conservative)
 * GC and do error catching.  Any calls to Hugs functions should be "protected"
 * by being placed inside this macro.
 *
 *   void entryPoint(arg1, arg2, result)
 *   T1 arg1;
 *   T2 arg2;
 *   T3 *result;
 *   {
 *       protect(doNothing(),
 *           ...
 *       );
 *   }
 *
 * Macro decomposed into BEGIN_PROTECT and END_PROTECT pieces so that i
 * can be used on some compilers (Mac?) that have limits on the size of
 * macro arguments.
 */
#define BEGIN_PROTECT \
  if (NULL == lastError) { \
      Cell dummy; \
      CStackBase = &dummy;              /* Save stack base for use in gc  */ \
      consGC = TRUE;                    /* conservative GC is the default */ \
      if (1) {
#define END_PROTECT \
      } else { \
	setError("Error occurred"); \
	normalTerminal(); \
      }	\
  }
#define protect(s)	BEGIN_PROTECT s; END_PROTECT

static Void    MkObject    Args((System::Object*));
static Object* EvalObject  Args((Void));
static Int     DoIO_Object Args((Object* __gc&));

/* Push an Object/DotNetPtr onto the stack */
static Void MkObject(Object* a)
{
#ifndef NO_DYNAMIC_TYPES
    Cell d = getTypeableDict(type);
    if (isNull(d)) {
      setError("MkObject: can't create Typeable instance");
      return 0;
    }
    protect(push(ap(ap(nameToDynamic,d),mkDotNetPtr(a,freeNetPtr))));
#else
    protect(push(mkDotNetPtr(a,freeNetPtr)));
#endif
}

static Object* EvalObject()          /* Evaluate a cell (:: Object)    */
{
    Cell d;
    BEGIN_PROTECT
	startEval();
#ifndef NO_DYNAMIC_TYPES
	d = getTypeableDict(type);
	if (isNull(d)) {
	    setError("EvalObject: can't create Typeable instance");
	    return 0;
	}
	safeEval(ap(ap(nameToDynamic,d),pop()));
#else
	safeEval(pop());
#endif
	normalTerminal();
	return getNP(whnfHead);
    END_PROTECT
    return 0;
}

/*
 * Evaluate a cell (:: IO DotNetPtr) return exit status
 */
static Int DoIO_Object(Object* __gc& phval)
{
    BEGIN_PROTECT
        Int exitCode = 0;
        Bool ok;
        StackPtr oldsp = sp;
        startEval();
#ifndef NO_DYNAMIC_TYPES
        ok = safeEval(ap(nameIORun,ap(nameRunDyn,pop())));
#else
        ok = safeEval(ap(nameIORun,pop()));
#endif
        if (!ok)
        {
            sp = oldsp-1;
            exitCode = 1;
	} else if (whnfHead == nameLeft) {
            safeEval(pop());
            exitCode = whnfInt;
        } else {
	    if (phval) {
	      safeEval(pop());
	      phval = getNP(whnfHead);
	    } else {
	      drop();
	    }
            exitCode = 0;
        }
        normalTerminal();
        if (sp != oldsp-1) {
            setError("doIO: unbalanced stack");
            return 1;
        }
        return exitCode;
    END_PROTECT;
    return -1; /* error code */
}

namespace Hugs {

System::String* Server::ClearError() {
  char* s = m_server->clearError();
  return new System::String(s);
}

//
// Method:  SetHugsArgs(String* argv[])
//
// Purpose: Configure the argument vector which
//          H98's System.getArgs returns.
//

void Server::SetHugsArgs(System::String* argv[]) {
  char __nogc* __nogc* args = new char*[argv.Length];
  int len = argv.Length;

  for (int i=0; i < len; i++) {
    args[i] = new char[argv[i]->Length + 1];
    args[i] = ToCharString(argv[i]);
  }
  m_server->setHugsArgs(len,args);

  /* Looks kind of silly; a better way? */
  for (int i=0; i < len; i++) {
    delete args[i];
  }
  delete args;

  return;
}

int    Server::GetNumScripts() {
  return m_server->getNumScripts();
}

void   Server::Reset(int i) {
  m_server->reset(i);
  return;
}

void   Server::SetOutputEnable (int i) {
  m_server->setOutputEnable(i);
  return;
}

void   Server::ChangeDir(System::String* dir) {
  char __nogc* dirStr = ToCharString(dir);
  m_server->changeDir(dirStr);
  FreeCharString(dirStr);
  return;
}

void   Server::LoadProject(System::String* proj) {
  char __nogc* projStr = ToCharString(proj);
  m_server->loadProject(projStr);
  FreeCharString(projStr);
  return;
}

void   Server::LoadFile(System::String* fname) {
  char __nogc* fnameStr = ToCharString(fname);
  m_server->loadProject(fnameStr);
  FreeCharString(fnameStr);
  return;
}

void   Server::LoadFromBuffer(System::String* haskMod) {
  char __nogc* hStr = ToCharString(haskMod);
  m_server->loadFromBuffer(hStr);
  FreeCharString(hStr);
  return;
}

void   Server::SetOptions(System::String* opts) {
  char __nogc* hStr = ToCharString(opts);
  m_server->setOptions(hStr);
  FreeCharString(hStr);
  return;
}

System::String* Server::GetOptions() {
  char* r = m_server->getOptions();
  return System::Runtime::InteropServices::Marshal::PtrToStringAnsi(r);
}

HVal Server::CompileExpr(System::String* mo,System::String* v) {
  char __nogc* moStr = ToCharString(mo);
  char __nogc* vStr = ToCharString(v);
  HVal res = m_server->compileExpr(moStr,vStr);
  FreeCharString(moStr);
  FreeCharString(vStr);
  return res;
}

void Server::GarbageCollect() {
  m_server->garbageCollect();
  return;
}

void  Server::LookupName(System::String* mo,System::String* v) {
  char __nogc* moStr = ToCharString(mo);
  char __nogc* vStr = ToCharString(v);
  m_server->lookupName(moStr,vStr);
  FreeCharString(moStr);
  FreeCharString(vStr);

  return;
}

void Server::mkInt(int i) {
  m_server->mkInt(i);
  return;
}

void Server::mkAddr(void* ptr) {
  m_server->mkAddr(ptr);
  return;
}

void Server::mkObject(Object* obj) {
  MkObject(obj);
  return;
}

void  Server::mkString(System::String* s) {
  char* str = ToCharString(s);
  m_server->mkString(str);
  FreeCharString(str);
  return;
}

void   Server::apply() {
  m_server->apply();
  return;
}

int Server::evalInt() {
  return m_server->evalInt();
}

void* Server::evalAddr() {
  return m_server->evalAddr();
}

Object* Server::evalObject() {
  return EvalObject();
}

System::String* Server::evalString() {
  char* str = m_server->evalString();
  return System::Runtime::InteropServices::Marshal::PtrToStringAnsi(str);
}

int Server::doIO() {
  return m_server->doIO();
}

int Server::doIO_Int(int* pRes) {
  return 0;
}

int Server::doIO_Addr(void** pRes)  {
  return 0;
}
int Server::doIO_Object(Object* __gc& pRes)  {
  return DoIO_Object(pRes);
}

HVal Server::popHVal() {
  HVal h = m_server->popHVal();
  return h;
}

void Server::pushHVal(HVal arg) {
  m_server->pushHVal(arg);
  return;
}

void Server::freeHVal(HVal arg) {
  m_server->freeHVal(arg);
  return;
}
};
<commit_msg>added machdep.h include<commit_after>//
// Managed C++ wrapper class around the Hugs server API.
//
#using <mscorlib.dll>
extern "C" {
#include "prelude.h"
#include "storage.h"
#include "machdep.h"
#include "connect.h"
};
#include "prim.h"
#include "HugsServ.h"

#define ToCharString(str) \
  static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str).ToPointer())
#define FreeCharString(pstr) System::Runtime::InteropServices::Marshal::FreeHGlobal(pstr)

extern "C" {
extern char* lastError;
extern char* ClearError();
extern Void  setError  (char*);
extern Bool  safeEval  (Cell c);
extern Void  startEval (Void);
};

/* All server entry points set CStackBase for the benefit of the (conservative)
 * GC and do error catching.  Any calls to Hugs functions should be "protected"
 * by being placed inside this macro.
 *
 *   void entryPoint(arg1, arg2, result)
 *   T1 arg1;
 *   T2 arg2;
 *   T3 *result;
 *   {
 *       protect(doNothing(),
 *           ...
 *       );
 *   }
 *
 * Macro decomposed into BEGIN_PROTECT and END_PROTECT pieces so that i
 * can be used on some compilers (Mac?) that have limits on the size of
 * macro arguments.
 */
#define BEGIN_PROTECT \
  if (NULL == lastError) { \
      Cell dummy; \
      CStackBase = &dummy;              /* Save stack base for use in gc  */ \
      consGC = TRUE;                    /* conservative GC is the default */ \
      if (1) {
#define END_PROTECT \
      } else { \
	setError("Error occurred"); \
	normalTerminal(); \
      }	\
  }
#define protect(s)	BEGIN_PROTECT s; END_PROTECT

static Void    MkObject    Args((System::Object*));
static Object* EvalObject  Args((Void));
static Int     DoIO_Object Args((Object* __gc&));

/* Push an Object/DotNetPtr onto the stack */
static Void MkObject(Object* a)
{
#ifndef NO_DYNAMIC_TYPES
    Cell d = getTypeableDict(type);
    if (isNull(d)) {
      setError("MkObject: can't create Typeable instance");
      return 0;
    }
    protect(push(ap(ap(nameToDynamic,d),mkDotNetPtr(a,freeNetPtr))));
#else
    protect(push(mkDotNetPtr(a,freeNetPtr)));
#endif
}

static Object* EvalObject()          /* Evaluate a cell (:: Object)    */
{
    Cell d;
    BEGIN_PROTECT
	startEval();
#ifndef NO_DYNAMIC_TYPES
	d = getTypeableDict(type);
	if (isNull(d)) {
	    setError("EvalObject: can't create Typeable instance");
	    return 0;
	}
	safeEval(ap(ap(nameToDynamic,d),pop()));
#else
	safeEval(pop());
#endif
	normalTerminal();
	return getNP(whnfHead);
    END_PROTECT
    return 0;
}

/*
 * Evaluate a cell (:: IO DotNetPtr) return exit status
 */
static Int DoIO_Object(Object* __gc& phval)
{
    BEGIN_PROTECT
        Int exitCode = 0;
        Bool ok;
        StackPtr oldsp = sp;
        startEval();
#ifndef NO_DYNAMIC_TYPES
        ok = safeEval(ap(nameIORun,ap(nameRunDyn,pop())));
#else
        ok = safeEval(ap(nameIORun,pop()));
#endif
        if (!ok)
        {
            sp = oldsp-1;
            exitCode = 1;
	} else if (whnfHead == nameLeft) {
            safeEval(pop());
            exitCode = whnfInt;
        } else {
	    if (phval) {
	      safeEval(pop());
	      phval = getNP(whnfHead);
	    } else {
	      drop();
	    }
            exitCode = 0;
        }
        normalTerminal();
        if (sp != oldsp-1) {
            setError("doIO: unbalanced stack");
            return 1;
        }
        return exitCode;
    END_PROTECT;
    return -1; /* error code */
}

namespace Hugs {

System::String* Server::ClearError() {
  char* s = m_server->clearError();
  return new System::String(s);
}

//
// Method:  SetHugsArgs(String* argv[])
//
// Purpose: Configure the argument vector which
//          H98's System.getArgs returns.
//

void Server::SetHugsArgs(System::String* argv[]) {
  char __nogc* __nogc* args = new char*[argv.Length];
  int len = argv.Length;

  for (int i=0; i < len; i++) {
    args[i] = new char[argv[i]->Length + 1];
    args[i] = ToCharString(argv[i]);
  }
  m_server->setHugsArgs(len,args);

  /* Looks kind of silly; a better way? */
  for (int i=0; i < len; i++) {
    delete args[i];
  }
  delete args;

  return;
}

int    Server::GetNumScripts() {
  return m_server->getNumScripts();
}

void   Server::Reset(int i) {
  m_server->reset(i);
  return;
}

void   Server::SetOutputEnable (int i) {
  m_server->setOutputEnable(i);
  return;
}

void   Server::ChangeDir(System::String* dir) {
  char __nogc* dirStr = ToCharString(dir);
  m_server->changeDir(dirStr);
  FreeCharString(dirStr);
  return;
}

void   Server::LoadProject(System::String* proj) {
  char __nogc* projStr = ToCharString(proj);
  m_server->loadProject(projStr);
  FreeCharString(projStr);
  return;
}

void   Server::LoadFile(System::String* fname) {
  char __nogc* fnameStr = ToCharString(fname);
  m_server->loadProject(fnameStr);
  FreeCharString(fnameStr);
  return;
}

void   Server::LoadFromBuffer(System::String* haskMod) {
  char __nogc* hStr = ToCharString(haskMod);
  m_server->loadFromBuffer(hStr);
  FreeCharString(hStr);
  return;
}

void   Server::SetOptions(System::String* opts) {
  char __nogc* hStr = ToCharString(opts);
  m_server->setOptions(hStr);
  FreeCharString(hStr);
  return;
}

System::String* Server::GetOptions() {
  char* r = m_server->getOptions();
  return System::Runtime::InteropServices::Marshal::PtrToStringAnsi(r);
}

HVal Server::CompileExpr(System::String* mo,System::String* v) {
  char __nogc* moStr = ToCharString(mo);
  char __nogc* vStr = ToCharString(v);
  HVal res = m_server->compileExpr(moStr,vStr);
  FreeCharString(moStr);
  FreeCharString(vStr);
  return res;
}

void Server::GarbageCollect() {
  m_server->garbageCollect();
  return;
}

void  Server::LookupName(System::String* mo,System::String* v) {
  char __nogc* moStr = ToCharString(mo);
  char __nogc* vStr = ToCharString(v);
  m_server->lookupName(moStr,vStr);
  FreeCharString(moStr);
  FreeCharString(vStr);

  return;
}

void Server::mkInt(int i) {
  m_server->mkInt(i);
  return;
}

void Server::mkAddr(void* ptr) {
  m_server->mkAddr(ptr);
  return;
}

void Server::mkObject(Object* obj) {
  MkObject(obj);
  return;
}

void  Server::mkString(System::String* s) {
  char* str = ToCharString(s);
  m_server->mkString(str);
  FreeCharString(str);
  return;
}

void   Server::apply() {
  m_server->apply();
  return;
}

int Server::evalInt() {
  return m_server->evalInt();
}

void* Server::evalAddr() {
  return m_server->evalAddr();
}

Object* Server::evalObject() {
  return EvalObject();
}

System::String* Server::evalString() {
  char* str = m_server->evalString();
  return System::Runtime::InteropServices::Marshal::PtrToStringAnsi(str);
}

int Server::doIO() {
  return m_server->doIO();
}

int Server::doIO_Int(int* pRes) {
  return 0;
}

int Server::doIO_Addr(void** pRes)  {
  return 0;
}
int Server::doIO_Object(Object* __gc& pRes)  {
  return DoIO_Object(pRes);
}

HVal Server::popHVal() {
  HVal h = m_server->popHVal();
  return h;
}

void Server::pushHVal(HVal arg) {
  m_server->pushHVal(arg);
  return;
}

void Server::freeHVal(HVal arg) {
  m_server->freeHVal(arg);
  return;
}
};
<|endoftext|>


<commit_before>#include "drivers/mpu6000.hpp"

#include "unit_config.hpp"

void MPU6000::init() {
  // Reset device.
  txbuf[0] = mpu6000::PWR_MGMT_1;
  txbuf[1] = 0x80;
  exchange(2);

  chThdSleepMilliseconds(100);   // TODO(yoos): Check whether or not datasheet specifies this holdoff.

  // Set sample rate to 1 kHz.
  txbuf[0] = mpu6000::SMPLRT_DIV;
  txbuf[1] = 0x00;
  exchange(2);

  // Set DLPF to 4 (20 Hz gyro bandwidth1 Hz accelerometer bandwidth)
  txbuf[0] = mpu6000::CONFIG;
  txbuf[1] = 0x04;
  exchange(2);

  // Wake up device and set clock source to Gyro Z.
  txbuf[0] = mpu6000::PWR_MGMT_1;
  txbuf[1] = 0x03;
  exchange(2);

  // Set gyro full range to 2000 dps. We first read in the current register
  // value so we can change what we need and leave everything else alone.
  // See DS p. 12.
  txbuf[0] = mpu6000::GYRO_CONFIG | (1<<7);
  exchange(2);
  chThdSleepMicroseconds(0);   // TODO(yoos): Without this, the GYRO_CONFIG register does not get set. This was not the case in the old C firmware. Why?
  txbuf[0] = mpu6000::GYRO_CONFIG;
  txbuf[1] = (rxbuf[1] & ~0x18) | 0x18;
  exchange(2);

  // Set accelerometer full range to 4 g. See DS p. 13.
  txbuf[0] = mpu6000::ACCEL_CONFIG | (1<<7);
  exchange(2);
  txbuf[0] = mpu6000::ACCEL_CONFIG;
  txbuf[1] = (rxbuf[1] & ~0x18) | 0x08;
  exchange(2);

  // Read once to clear out bad data?
  readGyro();
  readAccel();
}

gyroscope_reading_t MPU6000::readGyro() {
  gyroscope_reading_t reading;

  // Poll gyro
  txbuf[0] = mpu6000::GYRO_XOUT_H | (1<<7);
  exchange(7);

  // TODO(yoos): correct for thermal bias.
  reading.axes[0] = ((int16_t) ((rxbuf[1]<<8) | rxbuf[2])) / 16.384 * 3.1415926535 / 180.0 + unit_config::GYR_X_OFFSET;
  reading.axes[1] = ((int16_t) ((rxbuf[3]<<8) | rxbuf[4])) / 16.384 * 3.1415926535 / 180.0 + unit_config::GYR_Y_OFFSET;
  reading.axes[2] = ((int16_t) ((rxbuf[5]<<8) | rxbuf[6])) / 16.384 * 3.1415926535 / 180.0 + unit_config::GYR_Z_OFFSET;

  // Poll temp
  txbuf[0] = mpu6000::TEMP_OUT_H | (1<<7);
  exchange(3);

  float temp = ((int16_t) ((rxbuf[1]<<8) | rxbuf[2])) / 340 + 36.53;

  // DEBUG
  //char dbg_buf[16];
  //for (int i=0; i<16; i++) {
  //  dbg_buf[i] = 0;
  //}
  //chsnprintf(dbg_buf, 12, "%0.6f\r\n", reading.axes[2]);
  //chnWriteTimeout((BaseChannel*)&SD3, (uint8_t*)dbg_buf, 12, MS2ST(20));

  return reading;
}

accelerometer_reading_t MPU6000::readAccel() {
  accelerometer_reading_t reading;

  // Get data
  txbuf[0] = mpu6000::ACCEL_XOUT_H | (1<<7);
  exchange(7);
  reading.axes[0] = ((int16_t) ((rxbuf[1]<<8) | rxbuf[2])) / 8192.0 + unit_config::ACC_X_OFFSET;
  reading.axes[1] = ((int16_t) ((rxbuf[3]<<8) | rxbuf[4])) / 8192.0 + unit_config::ACC_Y_OFFSET;
  reading.axes[2] = -((int16_t) ((rxbuf[5]<<8) | rxbuf[6])) / 8192.0 + unit_config::ACC_Z_OFFSET;

  return reading;
}
<commit_msg>Negate MPU6000 X and Y axes.<commit_after>#include "drivers/mpu6000.hpp"

#include "unit_config.hpp"

void MPU6000::init() {
  // Reset device.
  txbuf[0] = mpu6000::PWR_MGMT_1;
  txbuf[1] = 0x80;
  exchange(2);

  chThdSleepMilliseconds(100);   // TODO(yoos): Check whether or not datasheet specifies this holdoff.

  // Set sample rate to 1 kHz.
  txbuf[0] = mpu6000::SMPLRT_DIV;
  txbuf[1] = 0x00;
  exchange(2);

  // Set DLPF to 4 (20 Hz gyro bandwidth1 Hz accelerometer bandwidth)
  txbuf[0] = mpu6000::CONFIG;
  txbuf[1] = 0x04;
  exchange(2);

  // Wake up device and set clock source to Gyro Z.
  txbuf[0] = mpu6000::PWR_MGMT_1;
  txbuf[1] = 0x03;
  exchange(2);

  // Set gyro full range to 2000 dps. We first read in the current register
  // value so we can change what we need and leave everything else alone.
  // See DS p. 12.
  txbuf[0] = mpu6000::GYRO_CONFIG | (1<<7);
  exchange(2);
  chThdSleepMicroseconds(0);   // TODO(yoos): Without this, the GYRO_CONFIG register does not get set. This was not the case in the old C firmware. Why?
  txbuf[0] = mpu6000::GYRO_CONFIG;
  txbuf[1] = (rxbuf[1] & ~0x18) | 0x18;
  exchange(2);

  // Set accelerometer full range to 4 g. See DS p. 13.
  txbuf[0] = mpu6000::ACCEL_CONFIG | (1<<7);
  exchange(2);
  txbuf[0] = mpu6000::ACCEL_CONFIG;
  txbuf[1] = (rxbuf[1] & ~0x18) | 0x08;
  exchange(2);

  // Read once to clear out bad data?
  readGyro();
  readAccel();
}

gyroscope_reading_t MPU6000::readGyro() {
  gyroscope_reading_t reading;

  // Poll gyro
  txbuf[0] = mpu6000::GYRO_XOUT_H | (1<<7);
  exchange(7);

  // TODO(yoos): correct for thermal bias.
  reading.axes[0] = -((int16_t) ((rxbuf[1]<<8) | rxbuf[2])) / 16.384 * 3.1415926535 / 180.0 + unit_config::GYR_X_OFFSET;
  reading.axes[1] = -((int16_t) ((rxbuf[3]<<8) | rxbuf[4])) / 16.384 * 3.1415926535 / 180.0 + unit_config::GYR_Y_OFFSET;
  reading.axes[2] = ((int16_t) ((rxbuf[5]<<8) | rxbuf[6])) / 16.384 * 3.1415926535 / 180.0 + unit_config::GYR_Z_OFFSET;

  // Poll temp
  txbuf[0] = mpu6000::TEMP_OUT_H | (1<<7);
  exchange(3);

  float temp = ((int16_t) ((rxbuf[1]<<8) | rxbuf[2])) / 340 + 36.53;

  // DEBUG
  //char dbg_buf[16];
  //for (int i=0; i<16; i++) {
  //  dbg_buf[i] = 0;
  //}
  //chsnprintf(dbg_buf, 12, "%0.6f\r\n", reading.axes[2]);
  //chnWriteTimeout((BaseChannel*)&SD3, (uint8_t*)dbg_buf, 12, MS2ST(20));

  return reading;
}

accelerometer_reading_t MPU6000::readAccel() {
  accelerometer_reading_t reading;

  // Get data
  txbuf[0] = mpu6000::ACCEL_XOUT_H | (1<<7);
  exchange(7);
  reading.axes[0] = ((int16_t) ((rxbuf[1]<<8) | rxbuf[2])) / 8192.0 + unit_config::ACC_X_OFFSET;
  reading.axes[1] = ((int16_t) ((rxbuf[3]<<8) | rxbuf[4])) / 8192.0 + unit_config::ACC_Y_OFFSET;
  reading.axes[2] = -((int16_t) ((rxbuf[5]<<8) | rxbuf[6])) / 8192.0 + unit_config::ACC_Z_OFFSET;

  return reading;
}
<|endoftext|>


<commit_before><commit_msg>glsl: Move the definition of precision_qualifier_allowed<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2016 Greenheart Games Pty. Ltd. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "nan.h"
#include "steam/steam_api.h"
#include "steam/steamencryptedappticket.h"
#include "v8.h"

#include "greenworks_async_workers.h"
#include "steam_api_registry.h"
#include "steam_id.h"

namespace greenworks {
namespace api {
namespace {

NAN_METHOD(GetAuthSessionTicket) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsFunction()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  Nan::Callback* success_callback =
      new Nan::Callback(info[0].As<v8::Function>());
  Nan::Callback* error_callback = NULL;
  if (info.Length() > 1 && info[1]->IsFunction())
    error_callback = new Nan::Callback(info[1].As<v8::Function>());
  Nan::AsyncQueueWorker(new greenworks::GetAuthSessionTicketWorker(
    success_callback, error_callback));
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(CancelAuthTicket) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsNumber()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  HAuthTicket h = info[1].As<v8::Number>()->Int32Value();
  SteamUser()->CancelAuthTicket(h);
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(GetEncryptedAppTicket) {
  Nan::HandleScope scope;
  if (info.Length() < 2 || !info[0]->IsString() || !info[1]->IsFunction()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  char* user_data = *(static_cast<v8::String::Utf8Value>(info[0]->ToString()));
  if (!user_data) {
    THROW_BAD_ARGS("Bad arguments");
  }
  Nan::Callback* success_callback =
      new Nan::Callback(info[1].As<v8::Function>());
  Nan::Callback* error_callback = NULL;
  if (info.Length() > 2 && info[2]->IsFunction())
    error_callback = new Nan::Callback(info[2].As<v8::Function>());
  Nan::AsyncQueueWorker(new greenworks::RequestEncryptedAppTicketWorker(
    user_data, success_callback, error_callback));
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(DecryptAppTicket) {
  Nan::HandleScope scope;
  if (info.Length() < 2 || !node::Buffer::HasInstance(info[0]) ||
      !node::Buffer::HasInstance(info[1])) {
    THROW_BAD_ARGS("Bad arguments");
  }
  char* encrypted_ticket_buf = node::Buffer::Data(info[0]);
  size_t encrypted_ticket_buf_size = node::Buffer::Length(info[0]);
  char* key_buf = node::Buffer::Data(info[1]);
  if (node::Buffer::Length(info[1]) !=
      k_nSteamEncryptedAppTicketSymmetricKeyLen) {
    THROW_BAD_ARGS("The key length is not matched");
  }
  uint8 key[k_nSteamEncryptedAppTicketSymmetricKeyLen];
  memcpy(key, key_buf, k_nSteamEncryptedAppTicketSymmetricKeyLen);

  uint8 decrypted_ticket[1024];
  uint32 decrypted_ticket_size = 1024;
  bool is_success = SteamEncryptedAppTicket_BDecryptTicket(
      reinterpret_cast<const uint8*>(encrypted_ticket_buf),
      encrypted_ticket_buf_size, decrypted_ticket, &decrypted_ticket_size, key,
      k_nSteamEncryptedAppTicketSymmetricKeyLen);

  if (!is_success) {
    info.GetReturnValue().Set(Nan::Undefined());
    return;
  }
  info.GetReturnValue().Set(
      Nan::CopyBuffer(reinterpret_cast<const char *>(decrypted_ticket),
                      decrypted_ticket_size)
          .ToLocalChecked());
}

NAN_METHOD(IsTicketForApp) {
  Nan::HandleScope scope;
  if (info.Length() < 2 || !node::Buffer::HasInstance(info[0]) ||
      info[1]->IsUint32()) {
    THROW_BAD_ARGS("Bad arguments");
  }

  char* decrypted_ticket_buf = node::Buffer::Data(info[0]);
  size_t decrypted_ticket_buf_size = node::Buffer::Length(info[0]);
  uint32 app_id = info[1]->Uint32Value();
  bool result = SteamEncryptedAppTicket_BIsTicketForApp(
      reinterpret_cast<uint8*>(decrypted_ticket_buf), decrypted_ticket_buf_size,
      app_id);
  info.GetReturnValue().Set(result);
}

NAN_METHOD(getTicketIssueTime) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !node::Buffer::HasInstance(info[0])) {
    THROW_BAD_ARGS("Bad arguments");
  }
  char* decrypted_ticket_buf = node::Buffer::Data(info[0]);
  size_t decrypted_ticket_buf_size = node::Buffer::Length(info[0]);
  uint32 time = SteamEncryptedAppTicket_GetTicketIssueTime(
      reinterpret_cast<uint8*>(decrypted_ticket_buf),
      decrypted_ticket_buf_size);
  info.GetReturnValue().Set(time);
}

NAN_METHOD(getTicketSteamId) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !node::Buffer::HasInstance(info[0])) {
    THROW_BAD_ARGS("Bad arguments");
  }
  char* decrypted_ticket_buf = node::Buffer::Data(info[0]);
  size_t decrypted_ticket_buf_size = node::Buffer::Length(info[0]);
  CSteamID steam_id;
  SteamEncryptedAppTicket_GetTicketSteamID(
      reinterpret_cast<uint8*>(decrypted_ticket_buf), decrypted_ticket_buf_size,
      &steam_id);
  info.GetReturnValue().Set(greenworks::SteamID::Create(steam_id));
}

void RegisterAPIs(v8::Handle<v8::Object> target) {
  Nan::Set(target,
           Nan::New("getAuthSessionTicket").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(GetAuthSessionTicket)->GetFunction());
  Nan::Set(target,
           Nan::New("getEncryptedAppTicket").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               GetEncryptedAppTicket)->GetFunction());
  Nan::Set(target,
           Nan::New("decryptAppTicket").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               DecryptAppTicket)->GetFunction());
  Nan::Set(target,
           Nan::New("isTicketForApp").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               IsTicketForApp)->GetFunction());
  Nan::Set(target,
           Nan::New("getTicketIssueTime").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               getTicketIssueTime)->GetFunction());
  Nan::Set(target,
           Nan::New("getTicketSteamId").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               getTicketSteamId)->GetFunction());
  Nan::Set(target,
           Nan::New("cancelAuthTicket").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(CancelAuthTicket)->GetFunction());
}

SteamAPIRegistry::Add X(RegisterAPIs);

}  // namespace
}  // namespace api
}  // namespace greenworks
<commit_msg>Add getTicketAppId API.<commit_after>// Copyright (c) 2016 Greenheart Games Pty. Ltd. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "nan.h"
#include "steam/steam_api.h"
#include "steam/steamencryptedappticket.h"
#include "v8.h"

#include "greenworks_async_workers.h"
#include "steam_api_registry.h"
#include "steam_id.h"

namespace greenworks {
namespace api {
namespace {

NAN_METHOD(GetAuthSessionTicket) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsFunction()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  Nan::Callback* success_callback =
      new Nan::Callback(info[0].As<v8::Function>());
  Nan::Callback* error_callback = NULL;
  if (info.Length() > 1 && info[1]->IsFunction())
    error_callback = new Nan::Callback(info[1].As<v8::Function>());
  Nan::AsyncQueueWorker(new greenworks::GetAuthSessionTicketWorker(
    success_callback, error_callback));
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(CancelAuthTicket) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsNumber()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  HAuthTicket h = info[1].As<v8::Number>()->Int32Value();
  SteamUser()->CancelAuthTicket(h);
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(GetEncryptedAppTicket) {
  Nan::HandleScope scope;
  if (info.Length() < 2 || !info[0]->IsString() || !info[1]->IsFunction()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  char* user_data = *(static_cast<v8::String::Utf8Value>(info[0]->ToString()));
  if (!user_data) {
    THROW_BAD_ARGS("Bad arguments");
  }
  Nan::Callback* success_callback =
      new Nan::Callback(info[1].As<v8::Function>());
  Nan::Callback* error_callback = NULL;
  if (info.Length() > 2 && info[2]->IsFunction())
    error_callback = new Nan::Callback(info[2].As<v8::Function>());
  Nan::AsyncQueueWorker(new greenworks::RequestEncryptedAppTicketWorker(
    user_data, success_callback, error_callback));
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(DecryptAppTicket) {
  Nan::HandleScope scope;
  if (info.Length() < 2 || !node::Buffer::HasInstance(info[0]) ||
      !node::Buffer::HasInstance(info[1])) {
    THROW_BAD_ARGS("Bad arguments");
  }
  char* encrypted_ticket_buf = node::Buffer::Data(info[0]);
  size_t encrypted_ticket_buf_size = node::Buffer::Length(info[0]);
  char* key_buf = node::Buffer::Data(info[1]);
  if (node::Buffer::Length(info[1]) !=
      k_nSteamEncryptedAppTicketSymmetricKeyLen) {
    THROW_BAD_ARGS("The key length is not matched");
  }
  uint8 key[k_nSteamEncryptedAppTicketSymmetricKeyLen];
  memcpy(key, key_buf, k_nSteamEncryptedAppTicketSymmetricKeyLen);

  uint8 decrypted_ticket[1024];
  uint32 decrypted_ticket_size = 1024;
  bool is_success = SteamEncryptedAppTicket_BDecryptTicket(
      reinterpret_cast<const uint8*>(encrypted_ticket_buf),
      encrypted_ticket_buf_size, decrypted_ticket, &decrypted_ticket_size, key,
      k_nSteamEncryptedAppTicketSymmetricKeyLen);

  if (!is_success) {
    info.GetReturnValue().Set(Nan::Undefined());
    return;
  }
  info.GetReturnValue().Set(
      Nan::CopyBuffer(reinterpret_cast<const char *>(decrypted_ticket),
                      decrypted_ticket_size)
          .ToLocalChecked());
}

NAN_METHOD(IsTicketForApp) {
  Nan::HandleScope scope;
  if (info.Length() < 2 || !node::Buffer::HasInstance(info[0]) ||
      info[1]->IsUint32()) {
    THROW_BAD_ARGS("Bad arguments");
  }

  char* decrypted_ticket_buf = node::Buffer::Data(info[0]);
  size_t decrypted_ticket_buf_size = node::Buffer::Length(info[0]);
  uint32 app_id = info[1]->Uint32Value();
  bool result = SteamEncryptedAppTicket_BIsTicketForApp(
      reinterpret_cast<uint8*>(decrypted_ticket_buf), decrypted_ticket_buf_size,
      app_id);
  info.GetReturnValue().Set(result);
}

NAN_METHOD(getTicketIssueTime) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !node::Buffer::HasInstance(info[0])) {
    THROW_BAD_ARGS("Bad arguments");
  }
  char* decrypted_ticket_buf = node::Buffer::Data(info[0]);
  size_t decrypted_ticket_buf_size = node::Buffer::Length(info[0]);
  uint32 time = SteamEncryptedAppTicket_GetTicketIssueTime(
      reinterpret_cast<uint8*>(decrypted_ticket_buf),
      decrypted_ticket_buf_size);
  info.GetReturnValue().Set(time);
}

NAN_METHOD(getTicketSteamId) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !node::Buffer::HasInstance(info[0])) {
    THROW_BAD_ARGS("Bad arguments");
  }
  char* decrypted_ticket_buf = node::Buffer::Data(info[0]);
  size_t decrypted_ticket_buf_size = node::Buffer::Length(info[0]);
  CSteamID steam_id;
  SteamEncryptedAppTicket_GetTicketSteamID(
      reinterpret_cast<uint8*>(decrypted_ticket_buf), decrypted_ticket_buf_size,
      &steam_id);
  info.GetReturnValue().Set(greenworks::SteamID::Create(steam_id));
}

NAN_METHOD(getTicketAppId) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !node::Buffer::HasInstance(info[0])) {
    THROW_BAD_ARGS("Bad arguments");
  }
  char* decrypted_ticket_buf = node::Buffer::Data(info[0]);
  size_t decrypted_ticket_buf_size = node::Buffer::Length(info[0]);
  uint32 app_id = SteamEncryptedAppTicket_GetTicketAppID(
      reinterpret_cast<uint8*>(decrypted_ticket_buf),
      decrypted_ticket_buf_size);
  info.GetReturnValue().Set(app_id);
}

void RegisterAPIs(v8::Handle<v8::Object> target) {
  Nan::Set(target,
           Nan::New("getAuthSessionTicket").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(GetAuthSessionTicket)->GetFunction());
  Nan::Set(target,
           Nan::New("getEncryptedAppTicket").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               GetEncryptedAppTicket)->GetFunction());
  Nan::Set(target,
           Nan::New("decryptAppTicket").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               DecryptAppTicket)->GetFunction());
  Nan::Set(target,
           Nan::New("isTicketForApp").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               IsTicketForApp)->GetFunction());
  Nan::Set(target,
           Nan::New("getTicketIssueTime").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               getTicketIssueTime)->GetFunction());
  Nan::Set(target,
           Nan::New("getTicketSteamId").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               getTicketSteamId)->GetFunction());
  Nan::Set(target,
           Nan::New("getTicketAppId").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(
               getTicketAppId)->GetFunction());
  Nan::Set(target,
           Nan::New("cancelAuthTicket").ToLocalChecked(),
           Nan::New<v8::FunctionTemplate>(CancelAuthTicket)->GetFunction());
}

SteamAPIRegistry::Add X(RegisterAPIs);

}  // namespace
}  // namespace api
}  // namespace greenworks
<|endoftext|>


<commit_before>///
/// @file   main.cpp
/// @brief  primesieve console application.
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/ParallelPrimeSieve.hpp>
#include "cmdoptions.hpp"

#include <iostream>
#include <exception>
#include <iomanip>
#include <algorithm>
#include <string>

using namespace std;
using namespace primesieve;

namespace {

void printResults(ParallelPrimeSieve& pps, CmdOptions& opts)
{
  cout << left;

  const string labels[] =
  {
    "Primes",
    "Twin primes",
    "Prime triplets",
    "Prime quadruplets",
    "Prime quintuplets",
    "Prime sextuplets"
  };

  // largest label size, computed below
  int size = 0;

  for (int i = 0; i < 6; i++)
  {
    if (pps.isCount(i))
    {
      int label_size = (int) labels[i].size();
      size = max(size, label_size);
    }
  }

  if (opts.time)
  {
    int label_size = (int) string("Seconds").size();
    size = max(size, label_size);
  }

  // print results
  for (int i = 0; i < 6; i++)
  {
    if (pps.isCount(i))
      cout << setw(size) << labels[i] << " : "
           << pps.getCount(i) << endl;
  }

  if (opts.time)
    cout << setw(size) << "Seconds" << " : "
         << fixed << setprecision(3) << pps.getSeconds()
         << endl;
}

/// Used to count and print primes and prime k-tuplets
void sieve(CmdOptions& opts)
{
  ParallelPrimeSieve pps;
  deque<uint64_t>& numbers = opts.numbers;

  if (opts.flags     != 0) pps.setFlags(opts.flags);
  if (opts.sieveSize != 0) pps.setSieveSize(opts.sieveSize);
  if (opts.threads   != 0) pps.setNumThreads(opts.threads);
  else if (pps.isPrint())  pps.setNumThreads(1);

  if (numbers.size() < 2)
    numbers.push_front(0);

  pps.setStart(numbers[0]);
  pps.setStop(numbers[1]);

  if (!opts.quiet)
  {
    cout << "Sieve size = " << pps.getSieveSize() << " kilobytes" << endl;
    cout << "Threads    = " << pps.idealNumThreads() << endl;
  }

  if (opts.status)
    pps.addFlags(pps.PRINT_STATUS);

  pps.sieve();
  printResults(pps, opts);
}

void nthPrime(CmdOptions& opts)
{
  ParallelPrimeSieve pps;
  deque<uint64_t>& numbers = opts.numbers;

  if (opts.flags     != 0) pps.setFlags(opts.flags);
  if (opts.sieveSize != 0) pps.setSieveSize(opts.sieveSize);
  if (opts.threads   != 0) pps.setNumThreads(opts.threads);

  if (numbers.size() < 2)
    numbers.push_back(0);

  uint64_t n = numbers[0];
  uint64_t start = numbers[1];
  uint64_t nthPrime = pps.nthPrime(n, start);

  cout << "Nth prime : " << nthPrime << endl;

  if (opts.time)
    cout << "Seconds   : " << fixed << setprecision(3)
         << pps.getSeconds() << endl;
}

} // namespace

int main(int argc, char** argv)
{
  CmdOptions opts = parseOptions(argc, argv);

  try
  {
    if (opts.nthPrime)
      nthPrime(opts);
    else
      sieve(opts);
  }
  catch (exception& e)
  {
    cerr << "Error: " << e.what() << "." << endl
         << "Try `primesieve --help' for more information." << endl;

    return 1;
  }

  return 0;
}
<commit_msg>Print time before primes<commit_after>///
/// @file   main.cpp
/// @brief  primesieve console application.
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/ParallelPrimeSieve.hpp>
#include "cmdoptions.hpp"

#include <iostream>
#include <exception>
#include <iomanip>
#include <algorithm>
#include <string>

using namespace std;
using namespace primesieve;

namespace {

void printResults(ParallelPrimeSieve& pps, CmdOptions& opts)
{
  cout << left;

  const string labels[] =
  {
    "Primes",
    "Twin primes",
    "Prime triplets",
    "Prime quadruplets",
    "Prime quintuplets",
    "Prime sextuplets"
  };

  // largest label size, computed below
  int size = 0;

  for (int i = 0; i < 6; i++)
  {
    if (pps.isCount(i))
    {
      int label_size = (int) labels[i].size();
      size = max(size, label_size);
    }
  }

  if (opts.time)
  {
    int label_size = (int) string("Seconds").size();
    size = max(size, label_size);
  }

  if (opts.time)
    cout << setw(size) << "Seconds" << " : "
         << fixed << setprecision(3) << pps.getSeconds()
         << endl;

  // print results
  for (int i = 0; i < 6; i++)
  {
    if (pps.isCount(i))
      cout << setw(size) << labels[i] << " : "
           << pps.getCount(i) << endl;
  }
}

/// Used to count and print primes and prime k-tuplets
void sieve(CmdOptions& opts)
{
  ParallelPrimeSieve pps;
  deque<uint64_t>& numbers = opts.numbers;

  if (opts.flags     != 0) pps.setFlags(opts.flags);
  if (opts.sieveSize != 0) pps.setSieveSize(opts.sieveSize);
  if (opts.threads   != 0) pps.setNumThreads(opts.threads);
  else if (pps.isPrint())  pps.setNumThreads(1);

  if (numbers.size() < 2)
    numbers.push_front(0);

  pps.setStart(numbers[0]);
  pps.setStop(numbers[1]);

  if (!opts.quiet)
  {
    cout << "Sieve size = " << pps.getSieveSize() << " kilobytes" << endl;
    cout << "Threads = " << pps.idealNumThreads() << endl;
  }

  if (opts.status)
    pps.addFlags(pps.PRINT_STATUS);

  pps.sieve();
  printResults(pps, opts);
}

void nthPrime(CmdOptions& opts)
{
  ParallelPrimeSieve pps;
  deque<uint64_t>& numbers = opts.numbers;

  if (opts.flags     != 0) pps.setFlags(opts.flags);
  if (opts.sieveSize != 0) pps.setSieveSize(opts.sieveSize);
  if (opts.threads   != 0) pps.setNumThreads(opts.threads);

  if (numbers.size() < 2)
    numbers.push_back(0);

  uint64_t n = numbers[0];
  uint64_t start = numbers[1];
  uint64_t nthPrime = pps.nthPrime(n, start);

  if (opts.time)
    cout << "Seconds   : " << fixed << setprecision(3)
         << pps.getSeconds() << endl;

  cout << "Nth prime : " << nthPrime << endl;
}

} // namespace

int main(int argc, char** argv)
{
  CmdOptions opts = parseOptions(argc, argv);

  try
  {
    if (opts.nthPrime)
      nthPrime(opts);
    else
      sieve(opts);
  }
  catch (exception& e)
  {
    cerr << "Error: " << e.what() << "." << endl
         << "Try `primesieve --help' for more information." << endl;

    return 1;
  }

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 *          Ali Saidi
 */

#include <string>

#include "arch/alpha/ev5.hh"
#include "arch/alpha/vtophys.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "mem/vport.hh"

using namespace std;
using namespace AlphaISA;

AlphaISA::PageTableEntry
AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr)
{
    Addr level1_pte = ptbr + vaddr.level1();
    AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
    if (!level1.valid()) {
        DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr);
        return 0;
    }

    Addr level2_pte = level1.paddr() + vaddr.level2();
    AlphaISA::PageTableEntry level2 = mem->read<uint64_t>(level2_pte);
    if (!level2.valid()) {
        DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr);
        return 0;
    }

    Addr level3_pte = level2.paddr() + vaddr.level3();
    AlphaISA::PageTableEntry level3 = mem->read<uint64_t>(level3_pte);
    if (!level3.valid()) {
        DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
        return 0;
    }
    return level3;
}

Addr
AlphaISA::vtophys(Addr vaddr)
{
    Addr paddr = 0;
    if (AlphaISA::IsUSeg(vaddr))
        DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
    else if (AlphaISA::IsK0Seg(vaddr))
        paddr = AlphaISA::K0Seg2Phys(vaddr);
    else
        panic("vtophys: ptbr is not set on virtual lookup");

    DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);

    return paddr;
}

Addr
AlphaISA::vtophys(ThreadContext *tc, Addr addr)
{
    AlphaISA::VAddr vaddr = addr;
    Addr ptbr = tc->readMiscReg(AlphaISA::IPR_PALtemp20);
    Addr paddr = 0;
    //@todo Andrew couldn't remember why he commented some of this code
    //so I put it back in. Perhaps something to do with gdb debugging?
    if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) {
        paddr = vaddr & ~ULL(1);
    } else {
        if (AlphaISA::IsK0Seg(vaddr)) {
            paddr = AlphaISA::K0Seg2Phys(vaddr);
        } else if (!ptbr) {
            paddr = vaddr;
        } else {
            AlphaISA::PageTableEntry pte =
                kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
            if (pte.valid())
                paddr = pte.paddr() | vaddr.offset();
        }
    }

    DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);

    return paddr;
}

void
AlphaISA::CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
{
    uint8_t *dst = (uint8_t *)dest;
    VirtualPort *vp = tc->getVirtPort(tc);

    vp->readBlob(src, dst, cplen);

    tc->delVirtPort(vp);

}

void
AlphaISA::CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
{
    uint8_t *src = (uint8_t *)source;
    VirtualPort *vp = tc->getVirtPort(tc);

    vp->writeBlob(dest, src, cplen);

    tc->delVirtPort(vp);
}

void
AlphaISA::CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
{
    int len = 0;
    VirtualPort *vp = tc->getVirtPort(tc);

    do {
        vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
        len++;
    } while (len < maxlen && dst[len] != 0 );

    tc->delVirtPort(vp);
    dst[len] = 0;
}

void
AlphaISA::CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
{
    VirtualPort *vp = tc->getVirtPort(tc);
    for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done();
            gen.next())
    {
        vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
        src += gen.size();
    }
    tc->delVirtPort(vp);
}
<commit_msg>fix a bug in CopyStringOut. dprintk appears to work again.<commit_after>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 *          Ali Saidi
 */

#include <string>

#include "arch/alpha/ev5.hh"
#include "arch/alpha/vtophys.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "mem/vport.hh"

using namespace std;
using namespace AlphaISA;

AlphaISA::PageTableEntry
AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr)
{
    Addr level1_pte = ptbr + vaddr.level1();
    AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
    if (!level1.valid()) {
        DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr);
        return 0;
    }

    Addr level2_pte = level1.paddr() + vaddr.level2();
    AlphaISA::PageTableEntry level2 = mem->read<uint64_t>(level2_pte);
    if (!level2.valid()) {
        DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr);
        return 0;
    }

    Addr level3_pte = level2.paddr() + vaddr.level3();
    AlphaISA::PageTableEntry level3 = mem->read<uint64_t>(level3_pte);
    if (!level3.valid()) {
        DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
        return 0;
    }
    return level3;
}

Addr
AlphaISA::vtophys(Addr vaddr)
{
    Addr paddr = 0;
    if (AlphaISA::IsUSeg(vaddr))
        DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
    else if (AlphaISA::IsK0Seg(vaddr))
        paddr = AlphaISA::K0Seg2Phys(vaddr);
    else
        panic("vtophys: ptbr is not set on virtual lookup");

    DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);

    return paddr;
}

Addr
AlphaISA::vtophys(ThreadContext *tc, Addr addr)
{
    AlphaISA::VAddr vaddr = addr;
    Addr ptbr = tc->readMiscReg(AlphaISA::IPR_PALtemp20);
    Addr paddr = 0;
    //@todo Andrew couldn't remember why he commented some of this code
    //so I put it back in. Perhaps something to do with gdb debugging?
    if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) {
        paddr = vaddr & ~ULL(1);
    } else {
        if (AlphaISA::IsK0Seg(vaddr)) {
            paddr = AlphaISA::K0Seg2Phys(vaddr);
        } else if (!ptbr) {
            paddr = vaddr;
        } else {
            AlphaISA::PageTableEntry pte =
                kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
            if (pte.valid())
                paddr = pte.paddr() | vaddr.offset();
        }
    }

    DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);

    return paddr;
}

void
AlphaISA::CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
{
    uint8_t *dst = (uint8_t *)dest;
    VirtualPort *vp = tc->getVirtPort(tc);

    vp->readBlob(src, dst, cplen);

    tc->delVirtPort(vp);

}

void
AlphaISA::CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
{
    uint8_t *src = (uint8_t *)source;
    VirtualPort *vp = tc->getVirtPort(tc);

    vp->writeBlob(dest, src, cplen);

    tc->delVirtPort(vp);
}

void
AlphaISA::CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
{
    int len = 0;
    char *start = dst;
    VirtualPort *vp = tc->getVirtPort(tc);

    do {
        vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
    } while (len < maxlen && start[len++] != 0 );

    tc->delVirtPort(vp);
    dst[len] = 0;
}

void
AlphaISA::CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
{
    VirtualPort *vp = tc->getVirtPort(tc);
    for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done();
            gen.next())
    {
        vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
        src += gen.size();
    }
    tc->delVirtPort(vp);
}
<|endoftext|>