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

/** \file Neighbor.cc
 * \brief
 *
 */

#include <stdint.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <glob.h>
#include <errno.h>

#include <tcl.h>
#include "tcl_util.h"

#include "logger.h"
#include "util.h"
#include "Neighbor.h"
#include "Interface.h"

/*
 * I do not like this - try to eliminate OS defines
 */
#if defined(__APPLE__) || defined(__darwin__)
/* OSX seems not to define these. */
#ifndef s6_addr16
#define s6_addr16 __u6_addr.__u6_addr16
#endif
#ifndef s6_addr32
#define s6_addr32 __u6_addr.__u6_addr32
#endif
#endif

namespace { int debug = 0; }

/**
 */
void
Network::Node::uuid( UUID& that ) {
    _uuid = that;
    _ordinal = 255;
    valid = true;
    // log_notice( "new node allocated with uuid %s", _uuid.to_s() );
}

/**
 */
void
Network::Node::ordinal( uint8_t value ) {
    _ordinal = value;
    // log_notice( "node%d %s", _ordinal, _uuid.to_s() );
}

/**
 */
bool
Network::Node::operator == ( UUID& that ) {
    return _uuid == that;
}

/**
 */
bool
Network::Node::operator != ( UUID& that ) {
    return _uuid != that;
}

/**
 * Used to iterate through the node list and clear the partner
 * bit in all entries.
 */
class ClearNodePartner : public Network::NodeIterator {
public:
    ClearNodePartner() {}
    virtual ~ClearNodePartner() {}
    virtual int operator() ( Network::Node& node ) {
        if ( node.not_partner() ) return 0;
        log_notice( "clear partner [%s]", node.uuid().to_s() );
        node.clear_partner();
        return 1;
    }
};

/**
 */
Network::Peer::~Peer() {
    if ( _name != NULL ) free( _name );
    _name = NULL;
}

/**
 * This one should be deprecated
 */
Network::Peer::Peer( Network::Node *__node, struct in6_addr *address )
: _node(__node), _ordinal(0), _name(NULL) {
    memcpy( &lladdr, address, sizeof lladdr );
    memset( &neighbor_updated, 0, sizeof neighbor_updated );
}

/**
 */
void
Network::Peer::node( Node *that ) {
    _node = that;

    /*
     * Here we have just discovered a new partner.  If this was the
     * cached partner, then the _node would already be a partner.
     * Since it was not and the neighbor is a partner - it must
     * have been discovered on priv0, which either overrides the
     * cached partner (node replace or the like) or this is the
     * first time we have discovered the partner.  Either way
     * we need to cache the newly discovered partner.
     */
    if ( is_partner() and _node->not_partner() ) {
        _node->make_partner();
        log_notice( "node %s is partner", _node->uuid().to_s() );
    }

    /*
     * Cases that are ignored:
     * peer->not_partner() and _node->not_partner()
     *   -- who cares about this neighbor
     *
     * peer->is_partner() and _node->is_partner()
     *   -- we already have all necessary state
     *
     */

    if ( debug < 2 ) return;
    char buffer[80];
    const char *address_string = inet_ntop(AF_INET6, &lladdr, buffer, sizeof buffer);
    log_notice( "%s at %s is node %s",
                        (_node->is_partner() ? "partner" : "neighbor"),
                        address_string, _node->uuid().to_s() );
}

/**
 */
Network::Node *
Network::Peer::node() const {
    return _node;
}

/**
 * Since this is a sort of allocation method, maybe this should check if
 * already valid and either disallow usage -- or at least report that the
 * address is changing.
 */
void
Network::Peer::address( struct in6_addr *addr ) {
    memcpy( &lladdr, addr, sizeof lladdr );
    valid = true;
    if ( debug < 2 ) return;
    char buffer[80];
    const char *address_string = inet_ntop(AF_INET6, addr, buffer, sizeof buffer);
    log_notice( "new neighbor %s", address_string );
}

/**
 */
void
Network::Peer::set_interface( bool set_private, uint8_t set_ordinal ) {
    _is_private = set_private;
    _ordinal = set_ordinal;
}

/**
 */
void
Network::Peer::set_interface_name( char *name ) {
    if ( name == NULL ) {			// If the new name is NULL...
       if ( _name != NULL ) {			// ...and the Peer had a name...
           free( _name );			//    ...free the old name...
           _name = NULL;			//    ...and invalidate the name.
       }
       return;
    }

    if ( _name != NULL ) {			// If the Peer already has a name...
        if ( strcmp( name, _name ) ) {		// ...and it is *not* the same name...
            free( _name );			//    ...free the old name...
            _name = strdup( name );		//    ...and copy the new name.
        }					// If it *is* the same name, don't do free()/strdup()
    } else {					// If the Peer does not have a name...
        _name = strdup( name );			// ...copy the new name.
    }
}

/**
 */
void
Network::Peer::copy_address( struct in6_addr *address ) const {
    memcpy( address, &lladdr, sizeof lladdr );
}

/**
 */
void
Network::Peer::touch_advertised() {
    gettimeofday( &neighbor_advertised, 0 );
}

/**
 */
void
Network::Peer::touch() {
    gettimeofday( &neighbor_updated, 0 );
}

/**
 */
int
Network::Peer::seconds_since_last_update() const {
    struct timeval now;
    gettimeofday( &now, 0 );
    return now.tv_sec - neighbor_updated.tv_sec;
}

/**
 */
bool
Network::Peer::operator == ( struct in6_addr& that ) {
    if ( that.s6_addr32[0] != lladdr.s6_addr32[0] ) return false;
    if ( that.s6_addr32[1] != lladdr.s6_addr32[1] ) return false;
    if ( that.s6_addr32[2] != lladdr.s6_addr32[2] ) return false;
    if ( that.s6_addr32[3] != lladdr.s6_addr32[3] ) return false;
    return true;
}

/**
 */
bool
Network::Peer::operator != ( struct in6_addr& that ) {
    if ( that.s6_addr32[0] != lladdr.s6_addr32[0] ) return true;
    if ( that.s6_addr32[1] != lladdr.s6_addr32[1] ) return true;
    if ( that.s6_addr32[2] != lladdr.s6_addr32[2] ) return true;
    if ( that.s6_addr32[3] != lladdr.s6_addr32[3] ) return true;
    return false;
}

/**
 */
bool
Network::Peer::has_address( struct in6_addr *address ) {
    if ( address->s6_addr32[0] != lladdr.s6_addr32[0] ) return false;
    if ( address->s6_addr32[1] != lladdr.s6_addr32[1] ) return false;
    if ( address->s6_addr32[2] != lladdr.s6_addr32[2] ) return false;
    if ( address->s6_addr32[3] != lladdr.s6_addr32[3] ) return false;
    return true;
}

/**
 * DEPRECATED
 */
bool
Network::Peer::send_topology_event( Network::Interface *interface ) {
    char node_ordinal = (node() == NULL) ? '?' : ('0' + node()->ordinal());
    log_notice( "sending event to spine for node%c:%s%d seen on %s",
                        node_ordinal,
                        is_private() ? "priv" : "biz", ordinal(),
                        interface->name() );

    char *event_name = const_cast<char*>("SuperNova::NetTopologyUpdate");
    pid_t child = fork();

    if ( child < 0 ) {
        log_err( "failed to send %s event - couldn't fork", event_name );
        return false;
    }

    _spine_notified = true;
    if ( child > 0 ) {
        int status;
        waitpid( child, &status, 0);
        return true;
    }

    char *argv[] = { const_cast<char*>("genevent"), event_name, 0 };
    char *envp[] = { 0 };
    if ( execve("/usr/lib/spine/bin/genevent", argv, envp) < 0 ) {
        log_err( "failed to send %s event - couldn't execve", event_name );
        _exit( 0 );
    }

    // NOT REACHED
    return true;
}

/**
 */
static void
construct_remote_interface_name( Network::Peer *neighbor, char *name, int size ) {

    if ( neighbor->name() != NULL ) {
        strncpy( name, neighbor->name(), size );
    } else {
        int ordinal = neighbor->ordinal();
        if ( neighbor->is_private() ) {
            if ( ordinal & 0x40 ) {
                int slot = ( ordinal & 0x3c ) >> 2;
                int port = ( ordinal & 0x03);
                snprintf( name, size, "sync_pci%dp%d", slot, port );
            } else {
                snprintf( name, size, "priv%d", ordinal );
            }
        } else {
            snprintf( name, size, "ibiz%d", ordinal );
        }
    }
}

/**
 */
void
Network::Peer::topology_changed( Network::Monitor *monitor, Network::Interface *interface ) {
    char node_ordinal = (node() == NULL) ? '?' : ('0' + node()->ordinal());
    char remote_interface_name[32];
    construct_remote_interface_name( this, remote_interface_name,
                                     sizeof(remote_interface_name) );
    log_notice( "Topology change: node%c:%s seen on %s",
                        node_ordinal, remote_interface_name, interface->name() );

    _spine_notified = true;
    monitor->topology_changed();
}

/**
 * need some way to find these objects...
 * use TCL ..hmmm
 */
bool Neighbor_Module( Tcl_Interp *interp ) {

    Tcl_Command command;

    Tcl_Namespace *ns = Tcl_CreateNamespace(interp, "Network", (ClientData)0, NULL);
    if ( ns == NULL ) {
        return false;
    }

    if ( Tcl_LinkVar(interp, "Network::debug", (char *)&debug, TCL_LINK_INT) != TCL_OK ) {
        log_err( "failed to link Network::debug" );
        exit( 1 );
    }

    command = Tcl_CreateObjCommand(interp, "Network::Monitor", Monitor_cmd, (ClientData)0, NULL);
    if ( command == NULL ) {
        // logger ?? want to report TCL Error
        return false;
    }

    command = Tcl_CreateObjCommand(interp, "Network::Probe", Probe_cmd, (ClientData)0, NULL);
    if ( command == NULL ) {
        // logger ?? want to report TCL Error
        return false;
    }

    command = Tcl_CreateObjCommand(interp, "Network::Manager", Manager_cmd, (ClientData)0, NULL);
    if ( command == NULL ) {
        // logger ?? want to report TCL Error
        return false;
    }

    if ( Network::Interface::Initialize(interp) == false ) {
        log_err( "Network::Interface::Initialize failed" );
        return false;
    }

    if ( Network::SharedNetwork::Initialize(interp) == false ) {
        log_err( "Network::SharedNetwork::Initialize failed" );
        return false;
    }

    if ( Network::Bridge::Initialize(interp) == false ) {
        log_err( "Network::Bridge::Initialize failed" );
        return false;
    }

    if ( Network::Tunnel::Initialize(interp) == false ) {
        log_err( "Network::Tunnel:Initialize failed" );
        return false;
    }

    return true;
}

/* vim: set autoindent expandtab sw=4 : */
<commit_msg>remove incorrect tcl init from neigh<commit_after>
/*
 * Copyright (c) 2012 Karl N. Redgate
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/** \file Neighbor.cc
 * \brief
 *
 */

#include <stdint.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <glob.h>
#include <errno.h>

#include <tcl.h>
#include "tcl_util.h"

#include "logger.h"
#include "util.h"
#include "Neighbor.h"
#include "Interface.h"

/*
 * I do not like this - try to eliminate OS defines
 */
#if defined(__APPLE__) || defined(__darwin__)
/* OSX seems not to define these. */
#ifndef s6_addr16
#define s6_addr16 __u6_addr.__u6_addr16
#endif
#ifndef s6_addr32
#define s6_addr32 __u6_addr.__u6_addr32
#endif
#endif

namespace { int debug = 0; }

/**
 */
void
Network::Node::uuid( UUID& that ) {
    _uuid = that;
    _ordinal = 255;
    valid = true;
    // log_notice( "new node allocated with uuid %s", _uuid.to_s() );
}

/**
 */
void
Network::Node::ordinal( uint8_t value ) {
    _ordinal = value;
    // log_notice( "node%d %s", _ordinal, _uuid.to_s() );
}

/**
 */
bool
Network::Node::operator == ( UUID& that ) {
    return _uuid == that;
}

/**
 */
bool
Network::Node::operator != ( UUID& that ) {
    return _uuid != that;
}

/**
 * Used to iterate through the node list and clear the partner
 * bit in all entries.
 */
class ClearNodePartner : public Network::NodeIterator {
public:
    ClearNodePartner() {}
    virtual ~ClearNodePartner() {}
    virtual int operator() ( Network::Node& node ) {
        if ( node.not_partner() ) return 0;
        log_notice( "clear partner [%s]", node.uuid().to_s() );
        node.clear_partner();
        return 1;
    }
};

/**
 */
Network::Peer::~Peer() {
    if ( _name != NULL ) free( _name );
    _name = NULL;
}

/**
 * This one should be deprecated
 */
Network::Peer::Peer( Network::Node *__node, struct in6_addr *address )
: _node(__node), _ordinal(0), _name(NULL) {
    memcpy( &lladdr, address, sizeof lladdr );
    memset( &neighbor_updated, 0, sizeof neighbor_updated );
}

/**
 */
void
Network::Peer::node( Node *that ) {
    _node = that;

    /*
     * Here we have just discovered a new partner.  If this was the
     * cached partner, then the _node would already be a partner.
     * Since it was not and the neighbor is a partner - it must
     * have been discovered on priv0, which either overrides the
     * cached partner (node replace or the like) or this is the
     * first time we have discovered the partner.  Either way
     * we need to cache the newly discovered partner.
     */
    if ( is_partner() and _node->not_partner() ) {
        _node->make_partner();
        log_notice( "node %s is partner", _node->uuid().to_s() );
    }

    /*
     * Cases that are ignored:
     * peer->not_partner() and _node->not_partner()
     *   -- who cares about this neighbor
     *
     * peer->is_partner() and _node->is_partner()
     *   -- we already have all necessary state
     *
     */

    if ( debug < 2 ) return;
    char buffer[80];
    const char *address_string = inet_ntop(AF_INET6, &lladdr, buffer, sizeof buffer);
    log_notice( "%s at %s is node %s",
                        (_node->is_partner() ? "partner" : "neighbor"),
                        address_string, _node->uuid().to_s() );
}

/**
 */
Network::Node *
Network::Peer::node() const {
    return _node;
}

/**
 * Since this is a sort of allocation method, maybe this should check if
 * already valid and either disallow usage -- or at least report that the
 * address is changing.
 */
void
Network::Peer::address( struct in6_addr *addr ) {
    memcpy( &lladdr, addr, sizeof lladdr );
    valid = true;
    if ( debug < 2 ) return;
    char buffer[80];
    const char *address_string = inet_ntop(AF_INET6, addr, buffer, sizeof buffer);
    log_notice( "new neighbor %s", address_string );
}

/**
 */
void
Network::Peer::set_interface( bool set_private, uint8_t set_ordinal ) {
    _is_private = set_private;
    _ordinal = set_ordinal;
}

/**
 */
void
Network::Peer::set_interface_name( char *name ) {
    if ( name == NULL ) {			// If the new name is NULL...
       if ( _name != NULL ) {			// ...and the Peer had a name...
           free( _name );			//    ...free the old name...
           _name = NULL;			//    ...and invalidate the name.
       }
       return;
    }

    if ( _name != NULL ) {			// If the Peer already has a name...
        if ( strcmp( name, _name ) ) {		// ...and it is *not* the same name...
            free( _name );			//    ...free the old name...
            _name = strdup( name );		//    ...and copy the new name.
        }					// If it *is* the same name, don't do free()/strdup()
    } else {					// If the Peer does not have a name...
        _name = strdup( name );			// ...copy the new name.
    }
}

/**
 */
void
Network::Peer::copy_address( struct in6_addr *address ) const {
    memcpy( address, &lladdr, sizeof lladdr );
}

/**
 */
void
Network::Peer::touch_advertised() {
    gettimeofday( &neighbor_advertised, 0 );
}

/**
 */
void
Network::Peer::touch() {
    gettimeofday( &neighbor_updated, 0 );
}

/**
 */
int
Network::Peer::seconds_since_last_update() const {
    struct timeval now;
    gettimeofday( &now, 0 );
    return now.tv_sec - neighbor_updated.tv_sec;
}

/**
 */
bool
Network::Peer::operator == ( struct in6_addr& that ) {
    if ( that.s6_addr32[0] != lladdr.s6_addr32[0] ) return false;
    if ( that.s6_addr32[1] != lladdr.s6_addr32[1] ) return false;
    if ( that.s6_addr32[2] != lladdr.s6_addr32[2] ) return false;
    if ( that.s6_addr32[3] != lladdr.s6_addr32[3] ) return false;
    return true;
}

/**
 */
bool
Network::Peer::operator != ( struct in6_addr& that ) {
    if ( that.s6_addr32[0] != lladdr.s6_addr32[0] ) return true;
    if ( that.s6_addr32[1] != lladdr.s6_addr32[1] ) return true;
    if ( that.s6_addr32[2] != lladdr.s6_addr32[2] ) return true;
    if ( that.s6_addr32[3] != lladdr.s6_addr32[3] ) return true;
    return false;
}

/**
 */
bool
Network::Peer::has_address( struct in6_addr *address ) {
    if ( address->s6_addr32[0] != lladdr.s6_addr32[0] ) return false;
    if ( address->s6_addr32[1] != lladdr.s6_addr32[1] ) return false;
    if ( address->s6_addr32[2] != lladdr.s6_addr32[2] ) return false;
    if ( address->s6_addr32[3] != lladdr.s6_addr32[3] ) return false;
    return true;
}

/**
 * DEPRECATED
 */
bool
Network::Peer::send_topology_event( Network::Interface *interface ) {
    char node_ordinal = (node() == NULL) ? '?' : ('0' + node()->ordinal());
    log_notice( "sending event to spine for node%c:%s%d seen on %s",
                        node_ordinal,
                        is_private() ? "priv" : "biz", ordinal(),
                        interface->name() );

    char *event_name = const_cast<char*>("SuperNova::NetTopologyUpdate");
    pid_t child = fork();

    if ( child < 0 ) {
        log_err( "failed to send %s event - couldn't fork", event_name );
        return false;
    }

    _spine_notified = true;
    if ( child > 0 ) {
        int status;
        waitpid( child, &status, 0);
        return true;
    }

    char *argv[] = { const_cast<char*>("genevent"), event_name, 0 };
    char *envp[] = { 0 };
    if ( execve("/usr/lib/spine/bin/genevent", argv, envp) < 0 ) {
        log_err( "failed to send %s event - couldn't execve", event_name );
        _exit( 0 );
    }

    // NOT REACHED
    return true;
}

/**
 */
static void
construct_remote_interface_name( Network::Peer *neighbor, char *name, int size ) {

    if ( neighbor->name() != NULL ) {
        strncpy( name, neighbor->name(), size );
    } else {
        int ordinal = neighbor->ordinal();
        if ( neighbor->is_private() ) {
            if ( ordinal & 0x40 ) {
                int slot = ( ordinal & 0x3c ) >> 2;
                int port = ( ordinal & 0x03);
                snprintf( name, size, "sync_pci%dp%d", slot, port );
            } else {
                snprintf( name, size, "priv%d", ordinal );
            }
        } else {
            snprintf( name, size, "ibiz%d", ordinal );
        }
    }
}

/**
 */
void
Network::Peer::topology_changed( Network::Monitor *monitor, Network::Interface *interface ) {
    char node_ordinal = (node() == NULL) ? '?' : ('0' + node()->ordinal());
    char remote_interface_name[32];
    construct_remote_interface_name( this, remote_interface_name,
                                     sizeof(remote_interface_name) );
    log_notice( "Topology change: node%c:%s seen on %s",
                        node_ordinal, remote_interface_name, interface->name() );

    _spine_notified = true;
    monitor->topology_changed();
}

/* vim: set autoindent expandtab sw=4 : */
<|endoftext|>


<commit_before>#include "NewDial.h"
//Constructor
NewDial::NewDial(){
	if(buf = (char *)malloc(BUF_SIZE+1)) memset(buf,0,BUF_SIZE+1); //Had to add one more, to avoid some bug
}

NewDial::NewDial(unsigned int radius, unsigned int minLimit, unsigned int setpoint, unsigned int maxLimit)
{
	if(buf = (char *)malloc(BUF_SIZE+1)) memset(buf,0,BUF_SIZE+1); //Had to add one more, to avoid some bug
	this->setSize(radius);
	this->setLimits(minLimit,setpoint,maxLimit);
	this->setColors(BLACK,BLUE,WHITE);
	init();
}

NewDial::~NewDial(){}

//Methods
void NewDial::init(){
	Indicator::init();
	this->hiLimit = scaleMax;
	this->lowLimit = scaleMin;
	this->currentValue = setpoint;
	this->maxDegree = 315;
	this->minDegree = 585;
	this->tickSize = 10;
	this->gap = 5;
	this->tickDegree = 45;
	this->showVal = true;
	this->showTicks = true;
}

void NewDial::clear(){
	for(int i = BUF_SIZE-1; i >= 0; i--)
	{
			buf[i] = 0;
	}
}

void NewDial::setSize(int radius){
	this->w = radius*2;
	this->h = radius*2;
	this->radius = radius;
}

void NewDial::drawBorder(){
	int color = fgColor;
	if(currentValue > hiLimit) color = hiLimitColor;
	if(currentValue < lowLimit) color = lowLimitColor;

	for(int i=0; i<borderWidth; i++)
	{
  	Tft.drawCircle(x,y,radius-i,color);
  	//Serial.print("Drawing border with r = ");Serial.println(radius-i);
  }
}

void NewDial::drawFace(){
	// Draw face
	Tft.fillCircle(x,y,radius,bgColor);

	// Draw border
  drawBorder();

	int X1,Y1,X2,Y2;
  // Draw ticks

  if(showTicks){
	  for(int i=maxDegree; i<=minDegree; i+=tickDegree)
	  {
	  	X1 = getX(x,i,radius-tickSize);
	    Y1 = getY(y,i,radius-tickSize);
	    X2 = getX(x,i,radius-borderWidth);
	    Y2 = getY(y,i,radius-borderWidth);
	    Tft.drawLine(X1,Y1,X2,Y2,borderColor);
	  }
	}else{
		int i = minDegree;
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,borderColor);

		i = maxDegree;
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,borderColor);
	}

  if(setpoint){
  	int i = map(setpoint,scaleMin,scaleMax,minDegree,maxDegree);
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,fgColor);
	}

  if(hiLimit < scaleMax){
  	int i = map(hiLimit,scaleMin,scaleMax,minDegree,maxDegree);
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,hiLimitColor);
	}

  if(lowLimit > scaleMin){
  	int i = map(lowLimit,scaleMin,scaleMax,minDegree,maxDegree);
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,lowLimitColor);
	}

}

void NewDial::drawNeedle(int cX, int cY, int degree, int radius, int color){
  degree = map(constrain(degree,scaleMin,scaleMax),scaleMin,scaleMax,585,315);

  int pX1,pY1,pX2,pY2,pX3,pY3;

  pX1 = getX(cX,degree-90,2);
  pY1 = getY(cY,degree-90,2);
  pX2 = getX(cX,degree+90,2);
  pY2 = getY(cY,degree+90,2);
  pX3 = getX(cX,degree,radius);
  pY3 = getY(cY,degree,radius);
  // Outer triangle
  Tft.drawLine(pX1,pY1,pX2,pY2,color);
  Tft.drawLine(pX1,pY1,pX3,pY3,color);
  Tft.drawLine(pX2,pY2,pX3,pY3,color);

  pX1 = getX(cX,degree-90,1);
  pY1 = getY(cY,degree-90,1);
  pX2 = getX(cX,degree+90,1);
  pY2 = getY(cY,degree+90,1);

  // Inner Triangle
  Tft.drawLine(pX1,pY1,pX2,pY2,color);
  Tft.drawLine(pX1,pY1,pX3,pY3,color);
  Tft.drawLine(pX2,pY2,pX3,pY3,color);

  // Center Line
  Tft.drawLine(cX,cY,pX3,pY3,color);
}

int NewDial::getX(int cX,int deg, int radius){
  return (cX + radius * cos(deg*PI/180));
}

int NewDial::getY(int cY, int deg, int radius){
  return (cY - radius * sin(deg*PI/180));
}

//Overriden virtual methods
void NewDial::show(){
	// Draw face
	drawFace();
	update();
}

void NewDial::update(){
	int color = fgColor;

	// Limit crossing forces border to redraw
	if(previousValue <= hiLimit && previousValue >= lowLimit){
		if(currentValue > hiLimit || currentValue < lowLimit) drawBorder();
	}
	if(previousValue > hiLimit){
		if(currentValue <= hiLimit) drawBorder();
	}
	if(previousValue < lowLimit){
		if(currentValue >= lowLimit) drawBorder();
	}

	// Draw needle
	drawNeedle(x,y,previousValue,radius-tickSize-gap,bgColor);
	if(currentValue > hiLimit) color = hiLimitColor;
	if(currentValue < lowLimit) color = lowLimitColor;
	drawNeedle(x,y,currentValue,radius-tickSize-gap,color);

	if(showVal){
		// Draw current value
		int dSpace;
		int fontSize = 2;
  	if(currentValue<10) dSpace = 3 * fontSize;
  	if(currentValue>=10) dSpace = 6 * fontSize;
  	if(currentValue>99) dSpace = 9 * fontSize;
  	Tft.fillRectangle(x-9*fontSize,y+radius-12*fontSize,18*fontSize,8*fontSize,bgColor);
  	Tft.drawNumber(currentValue,x-dSpace,y+radius-12*fontSize,fontSize,color);
	}
}
<commit_msg>Added rendering of min and max values in NewDial<commit_after>#include "NewDial.h"
//Constructor
NewDial::NewDial(){
	if(buf = (char *)malloc(BUF_SIZE+1)) memset(buf,0,BUF_SIZE+1); //Had to add one more, to avoid some bug
}

NewDial::NewDial(unsigned int radius, unsigned int minLimit, unsigned int setpoint, unsigned int maxLimit)
{
	if(buf = (char *)malloc(BUF_SIZE+1)) memset(buf,0,BUF_SIZE+1); //Had to add one more, to avoid some bug
	this->setSize(radius);
	this->setLimits(minLimit,setpoint,maxLimit);
	this->setColors(BLACK,BLUE,WHITE);
	init();
}

NewDial::~NewDial(){}

//Methods
void NewDial::init(){
	Indicator::init();
	this->hiLimit = scaleMax;
	this->lowLimit = scaleMin;
	this->currentValue = setpoint;
	this->maxDegree = 315;
	this->minDegree = 585;
	this->tickSize = 10;
	this->gap = 5;
	this->tickDegree = 45;
	this->showVal = true;
	this->showTicks = true;
}

void NewDial::clear(){
	for(int i = BUF_SIZE-1; i >= 0; i--)
	{
			buf[i] = 0;
	}
}

void NewDial::setSize(int radius){
	this->w = radius*2;
	this->h = radius*2;
	this->radius = radius;
}

void NewDial::drawBorder(){
	int color = fgColor;
	if(currentValue > hiLimit) color = hiLimitColor;
	if(currentValue < lowLimit) color = lowLimitColor;

	for(int i=0; i<borderWidth; i++)
	{
  	Tft.drawCircle(x,y,radius-i,color);
  	//Serial.print("Drawing border with r = ");Serial.println(radius-i);
  }
}

void NewDial::drawFace(){
	// Draw face
	Tft.fillCircle(x,y,radius,bgColor);

	// Draw border
  drawBorder();

	int X1,Y1,X2,Y2;

  // Draw ticks
  if(showTicks){
	  for(int i=maxDegree; i<=minDegree; i+=tickDegree)
	  {
	  	X1 = getX(x,i,radius-tickSize);
	    Y1 = getY(y,i,radius-tickSize);
	    X2 = getX(x,i,radius-borderWidth);
	    Y2 = getY(y,i,radius-borderWidth);
	    Tft.drawLine(X1,Y1,X2,Y2,borderColor);
	  }
	}else{
		int i = minDegree;
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,borderColor);

		i = maxDegree;
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,borderColor);
	}

	// Draw Setpoint line
  if(setpoint){
  	int i = map(setpoint,scaleMin,scaleMax,minDegree,maxDegree);
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,fgColor);
	}

	// Draw High limit line
  if(hiLimit < scaleMax){
  	int i = map(hiLimit,scaleMin,scaleMax,minDegree,maxDegree);
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,hiLimitColor);
	}

	// Draw Low Limit line
  if(lowLimit > scaleMin){
  	int i = map(lowLimit,scaleMin,scaleMax,minDegree,maxDegree);
    X1 = getX(x,i,radius-tickSize);
    Y1 = getY(y,i,radius-tickSize);
    X2 = getX(x,i,radius-borderWidth);
    Y2 = getY(y,i,radius-borderWidth);
    Tft.drawLine(X1,Y1,X2,Y2,lowLimitColor);
	}

	// Draw min value
	setNum(scaleMin);
  Tft.drawString(buf,x-radius+FONT_SPACE,y+radius-FONT_Y,1,borderColor);

	// Draw max value
	setNum(scaleMax);
	Tft.drawString(buf,getX(x,maxDegree,radius-tickSize),y+radius-FONT_Y,1,borderColor);

}

void NewDial::drawNeedle(int cX, int cY, int degree, int radius, int color){
  degree = map(constrain(degree,scaleMin,scaleMax),scaleMin,scaleMax,585,315);

  int pX1,pY1,pX2,pY2,pX3,pY3;

  pX1 = getX(cX,degree-90,2);
  pY1 = getY(cY,degree-90,2);
  pX2 = getX(cX,degree+90,2);
  pY2 = getY(cY,degree+90,2);
  pX3 = getX(cX,degree,radius);
  pY3 = getY(cY,degree,radius);
  // Outer triangle
  Tft.drawLine(pX1,pY1,pX2,pY2,color);
  Tft.drawLine(pX1,pY1,pX3,pY3,color);
  Tft.drawLine(pX2,pY2,pX3,pY3,color);

  pX1 = getX(cX,degree-90,1);
  pY1 = getY(cY,degree-90,1);
  pX2 = getX(cX,degree+90,1);
  pY2 = getY(cY,degree+90,1);

  // Inner Triangle
  Tft.drawLine(pX1,pY1,pX2,pY2,color);
  Tft.drawLine(pX1,pY1,pX3,pY3,color);
  Tft.drawLine(pX2,pY2,pX3,pY3,color);

  // Center Line
  Tft.drawLine(cX,cY,pX3,pY3,color);
}

int NewDial::getX(int cX,int deg, int radius){
  return (cX + radius * cos(deg*PI/180));
}

int NewDial::getY(int cY, int deg, int radius){
  return (cY - radius * sin(deg*PI/180));
}

//Overriden virtual methods
void NewDial::show(){
	// Draw face
	drawFace();
	update();
}

void NewDial::update(){
	int color = fgColor;

	// Limit crossing forces border to redraw
	if(previousValue <= hiLimit && previousValue >= lowLimit){
		if(currentValue > hiLimit || currentValue < lowLimit) drawBorder();
	}
	if(previousValue > hiLimit){
		if(currentValue <= hiLimit) drawBorder();
	}
	if(previousValue < lowLimit){
		if(currentValue >= lowLimit) drawBorder();
	}

	// Draw needle
	drawNeedle(x,y,previousValue,radius-tickSize-gap,bgColor);
	if(currentValue > hiLimit) color = hiLimitColor;
	if(currentValue < lowLimit) color = lowLimitColor;
	drawNeedle(x,y,currentValue,radius-tickSize-gap,color);

	if(showVal){
		// Draw current value
		int dSpace;
		int fontSize = 2;
  	if(currentValue<10) dSpace = 3 * fontSize;
  	if(currentValue>=10) dSpace = 6 * fontSize;
  	if(currentValue>99) dSpace = 9 * fontSize;
  	Tft.fillRectangle(x-9*fontSize,y+radius-12*fontSize,18*fontSize,8*fontSize,bgColor);
  	Tft.drawNumber(currentValue,x-dSpace,y+radius-12*fontSize,fontSize,color);
	}
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2009-2011 qiuu
    Copyright (C) 2016 Clownacy

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

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
    USA
*/

#include <cstdio>
#include <cstdlib>
#include <SDL2/SDL.h>

#include "Common.h"
#include "Tile.h"
#include "LevMap.h"
#include "Graphics.h"
#include "Screen.h"
#include "SelRect.h"
#include "Project.h"
#include "PrjHndl.h"
#include "Resource.h"
#ifdef _WIN32
#include "WinAPI.h"
#endif

Screen* MainScreen;
Project* CurProject = NULL;

int main(int argc, char* argv[])
{
    // Create our window
    MainScreen = new Screen;

    MainScreen->Fill(MainScreen->BackgroundColour.red, MainScreen->BackgroundColour.green, MainScreen->BackgroundColour.blue);

    // For backwards-compatibility, we want project files that are drag-and-dropped
    // onto the executable to be automatically loaded when it starts.
    // First, we have to make sure the file's actually there.
    FILE* prjfile = fopen(argv[1], "r");
    if (prjfile != NULL)
    {
	fclose(prjfile);
        CurProject = new Project(argv[1]);

#ifdef _WIN32
	WinAPI::EnableMenuBarOption(true, MENUBAR_FILE_SAVE);
	WinAPI::EnableMenuBarOption(true, MENUBAR_FILE_CLOSE);
#endif

        // Process initial display
        CurProject->Redraw();
    }

    bool CtrlPress = false;

    //SDL_EnableKeyRepeat(400,SDL_DEFAULT_REPEAT_INTERVAL);

    //Main Loop including event Handling
    bool quit = false;
    while (!quit)
    {
        SDL_Event event;

        while ((!quit) && SDL_WaitEvent(&event))
        {
            if (event.type == SDL_QUIT) quit = true;
            if (event.type == SDL_MOUSEBUTTONDOWN)
            {
		if (CurProject != NULL)
		{
                    CurProject->SelectionRect->Unselect();
                    //Checks if within selector bounds and selects tile
                    CurProject->LevelMap->CheckClickTile(event.button.x, event.button.y);
                    if (event.button.button == SDL_BUTTON_LEFT)
                        //Checks if valid map position and sets tile
                        CurProject->LevelMap->CheckSetTile(event.button.x, event.button.y);
                    else if (event.button.button == SDL_BUTTON_RIGHT) {
                        //Checks if valid map position and selects tile
                        CurProject->LevelMap->CheckSelectTile(event.button.x, event.button.y);
                        CurProject->SelectionRect->SelInit(event.button.x, event.button.y);
                    }
		}
            }
            if (event.type == SDL_MOUSEBUTTONUP)
            {
                if (event.button.button == SDL_BUTTON_RIGHT) {
		    if (CurProject != NULL)
		    {
                        //Checks if valid map position and selects tile
                        CurProject->LevelMap->CheckSelectTile(event.button.x, event.button.y);
                        CurProject->SelectionRect->SelFinalize(event.button.x, event.button.y);
		    }
                }
            }
            if (event.type == SDL_MOUSEMOTION)
            {
		if (CurProject != NULL)
		{
                    if (SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1))
                        CurProject->LevelMap->CheckSetTile(event.motion.x, event.motion.y);
                    else {
                        CurProject->LevelMap->RefreshTileScreen(event.motion.x - event.motion.xrel, event.motion.y - event.motion.yrel, true);
                        CurProject->LevelMap->DrawSelectedTile(event.motion.x, event.motion.y);
                    }
		}
            }
            if (event.type == SDL_KEYDOWN)
            {
                //secondary cases usually for German keyboard layout support
                switch(event.key.keysym.sym)
                {
                    case SDLK_RCTRL:
                    case SDLK_LCTRL:
                        CtrlPress = true; break;
                    case '/':
                    case '-':
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->CurSwapPriority();
                            else {
                                CurProject->SelectionRect->SwapPriority();
                                CurProject->LevelMap->DrawMap();
                                CurProject->SelectionRect->SelDrawRect();
                            }
			}
                        break;
                    case ',':
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->CurFlipX();
                            else {
                                CurProject->SelectionRect->FlipX();
                                CurProject->LevelMap->DrawMap();
                                CurProject->SelectionRect->SelDrawRect();
                            }
			}
                        break;
                    case '.':
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->CurFlipY();
                            else {
                                CurProject->SelectionRect->FlipY();
                                CurProject->LevelMap->DrawMap();
                                CurProject->SelectionRect->SelDrawRect();
                            }
			}
                        break;
                    case SDLK_RIGHT:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftRight();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_LEFT:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftLeft();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_DOWN:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftDown();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_UP:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftUp();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_DELETE:
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->ClearCurrentTile();
                            else {
                                CurProject->SelectionRect->clear();
                                CurProject->SelectionRect->AssignSection();
                                CurProject->LevelMap->DrawMap();
                            }
			}
                        break;
                    case SDLK_ESCAPE:
                        quit = true; break;
                    case SDLK_RETURN:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetTileSelected();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case '=':
                    case '':
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SelectTileCur();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_PAGEDOWN:
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->SelectedTileIncrID();
                            else {
                                CurProject->SelectionRect->IncrID();
                                CurProject->SelectionRect->AssignSection();
                                CurProject->LevelMap->DrawMap();
                            }
			}
                        break;
                    case SDLK_PAGEUP:
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->SelectedTileDecrID();
                            else {
                                CurProject->SelectionRect->DecrID();
                                CurProject->SelectionRect->AssignSection();
                                CurProject->LevelMap->DrawMap();
                            }
			}
                        break;
                    case SDLK_F1:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetPalCurrent(0);
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_F2:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetPalCurrent(1);
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_F3:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetPalCurrent(2);
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_F4:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetPalCurrent(3);
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_F5:
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->ToggleHighPriority();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case SDLK_F6:
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->ToggleLowPriority();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case SDLK_F9:
		        if (CurProject != NULL)
			{
                            CurProject->Save();
			}
			break;
                    case SDLK_F10: //redraw whole screen
		        if (CurProject != NULL)
			{
                            CurProject->Redraw();
			}
			break;
                    case SDLK_BACKSPACE:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftLeft();
                            CurProject->LevelMap->ClearCurrentTile();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case '[':
                    case '':
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->DecScreenOffset();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case '\'':
                    case '':
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->IncScreenOffset();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case ';':
                    case '':
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->DecScreenXOffset();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case '\\':
                    case '#':
                    case '+':
                    case ']':
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->IncScreenXOffset();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case SDLK_END:
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->IncSelOffset();
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_HOME:
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->DecSelOffset();
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_SPACE:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->ClearCurrentTile();
                            CurProject->LevelMap->CurShiftRight();
			}
			break;
                    default:
                        if (event.key.keysym.sym >= 'a' && event.key.keysym.sym <= 'z') {
                            if (CtrlPress) {
                                switch(event.key.keysym.sym)
                                {
                                    case 'c':
				        if (CurProject != NULL)
					{
                                            if (CurProject->SelectionRect->isActive()) {
                                                if (CurProject->CopyRect != NULL) delete CurProject->CopyRect;
                                                CurProject->CopyRect = new SelRect(CurProject->SelectionRect);
                                            }
					}
                                        break;
                                    case 'x':
				        if (CurProject != NULL)
					{
                                            if (CurProject->SelectionRect->isActive()) {
                                                if (CurProject->CopyRect != NULL) delete CurProject->CopyRect;
                                                CurProject->CopyRect = new SelRect(CurProject->SelectionRect);
                                                CurProject->SelectionRect->clear();
                                                CurProject->SelectionRect->AssignSection();
                                                CurProject->LevelMap->DrawMap();
                                            }
					}
                                        break;
                                    case 'v':
				        if (CurProject != NULL)
					{
                                            CurProject->CopyRect->PasteSection();
                                            CurProject->LevelMap->DrawMap();
					}
                                        break;
                                    case 'a':
				        if (CurProject != NULL)
					{
                                            CurProject->SelectionRect->SelInit(0, 0);
                                            CurProject->SelectionRect->SelFinalize(CurProject->PrjData->map.xSize*8, CurProject->PrjData->map.ySize*8);
					}
                                        break;
                                }
                            } else {
				if (CurProject != NULL)
				{
                                    CurProject->LevelMap->SetCurrentTile(event.key.keysym.sym - 'a' + CurProject->GfxStuff->GetTileOffset() + CurProject->PrjData->letterOffset);
                                    CurProject->LevelMap->CurShiftRight();
                                    CurProject->SelectionRect->Unselect();
				}
                            }
                        }
                        else if (event.key.keysym.sym >= '0' && event.key.keysym.sym <= '9') {
			    if (CurProject != NULL)
			    {
                                CurProject->LevelMap->SetCurrentTile(event.key.keysym.sym - '0' + CurProject->GfxStuff->GetTileOffset() + CurProject->PrjData->numberOffset);
                                CurProject->LevelMap->CurShiftRight();
                                CurProject->SelectionRect->Unselect();
			    }
                        }
                }
            }
            if (event.type == SDL_KEYUP)
            {
                switch(event.key.keysym.sym)
                {
                    case SDLK_RCTRL:
                    case SDLK_LCTRL:
                        CtrlPress = false; break;
                }
            }

#ifdef _WIN32
            if (event.type == SDL_SYSWMEVENT)
	    {
		    WinAPI::HandleWindowsEvent(&event);
	    }
#endif

            MainScreen->ProcessDisplay();
        }
    }
    return 0;
}
<commit_msg>Blank window no longer opens on non-Windows builds<commit_after>/*
    Copyright (C) 2009-2011 qiuu
    Copyright (C) 2016 Clownacy

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

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
    USA
*/

#include <cstdio>
#include <cstdlib>
#include <SDL2/SDL.h>

#include "Common.h"
#include "Tile.h"
#include "LevMap.h"
#include "Graphics.h"
#include "Screen.h"
#include "SelRect.h"
#include "Project.h"
#include "PrjHndl.h"
#include "Resource.h"
#ifdef _WIN32
#include "WinAPI.h"
#endif

Screen* MainScreen;
Project* CurProject = NULL;

int main(int argc, char* argv[])
{
    // Create our window
    MainScreen = new Screen;

    MainScreen->Fill(MainScreen->BackgroundColour.red, MainScreen->BackgroundColour.green, MainScreen->BackgroundColour.blue);

    // For backwards-compatibility, we want project files that are drag-and-dropped
    // onto the executable to be automatically loaded when it starts.
    // First, we have to make sure the file's actually there.
    FILE* prjfile = fopen(argv[1], "r");
#ifdef _WIN32
    // Windows build allows a blank window to open, where the user can open a
    // project file using the menu bar
    if (prjfile != NULL)
    {
	fclose(prjfile);
        CurProject = new Project(argv[1]);

	WinAPI::EnableMenuBarOption(true, MENUBAR_FILE_SAVE);
	WinAPI::EnableMenuBarOption(true, MENUBAR_FILE_CLOSE);

        // Process initial display
        CurProject->Redraw();
    }
#else
    if (prjfile == NULL)
    {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "You must supply the project file as a parameter", NULL);
        exit(1);
    }
    fclose(prjfile);
    CurProject = new Project(argv[1]);

    // Process initial display
    CurProject->Redraw();
#endif

    bool CtrlPress = false;

    //SDL_EnableKeyRepeat(400,SDL_DEFAULT_REPEAT_INTERVAL);

    //Main Loop including event Handling
    bool quit = false;
    while (!quit)
    {
        SDL_Event event;

        while ((!quit) && SDL_WaitEvent(&event))
        {
            if (event.type == SDL_QUIT) quit = true;
            if (event.type == SDL_MOUSEBUTTONDOWN)
            {
		if (CurProject != NULL)
		{
                    CurProject->SelectionRect->Unselect();
                    //Checks if within selector bounds and selects tile
                    CurProject->LevelMap->CheckClickTile(event.button.x, event.button.y);
                    if (event.button.button == SDL_BUTTON_LEFT)
                        //Checks if valid map position and sets tile
                        CurProject->LevelMap->CheckSetTile(event.button.x, event.button.y);
                    else if (event.button.button == SDL_BUTTON_RIGHT) {
                        //Checks if valid map position and selects tile
                        CurProject->LevelMap->CheckSelectTile(event.button.x, event.button.y);
                        CurProject->SelectionRect->SelInit(event.button.x, event.button.y);
                    }
		}
            }
            if (event.type == SDL_MOUSEBUTTONUP)
            {
                if (event.button.button == SDL_BUTTON_RIGHT) {
		    if (CurProject != NULL)
		    {
                        //Checks if valid map position and selects tile
                        CurProject->LevelMap->CheckSelectTile(event.button.x, event.button.y);
                        CurProject->SelectionRect->SelFinalize(event.button.x, event.button.y);
		    }
                }
            }
            if (event.type == SDL_MOUSEMOTION)
            {
		if (CurProject != NULL)
		{
                    if (SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1))
                        CurProject->LevelMap->CheckSetTile(event.motion.x, event.motion.y);
                    else {
                        CurProject->LevelMap->RefreshTileScreen(event.motion.x - event.motion.xrel, event.motion.y - event.motion.yrel, true);
                        CurProject->LevelMap->DrawSelectedTile(event.motion.x, event.motion.y);
                    }
		}
            }
            if (event.type == SDL_KEYDOWN)
            {
                //secondary cases usually for German keyboard layout support
                switch(event.key.keysym.sym)
                {
                    case SDLK_RCTRL:
                    case SDLK_LCTRL:
                        CtrlPress = true; break;
                    case '/':
                    case '-':
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->CurSwapPriority();
                            else {
                                CurProject->SelectionRect->SwapPriority();
                                CurProject->LevelMap->DrawMap();
                                CurProject->SelectionRect->SelDrawRect();
                            }
			}
                        break;
                    case ',':
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->CurFlipX();
                            else {
                                CurProject->SelectionRect->FlipX();
                                CurProject->LevelMap->DrawMap();
                                CurProject->SelectionRect->SelDrawRect();
                            }
			}
                        break;
                    case '.':
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->CurFlipY();
                            else {
                                CurProject->SelectionRect->FlipY();
                                CurProject->LevelMap->DrawMap();
                                CurProject->SelectionRect->SelDrawRect();
                            }
			}
                        break;
                    case SDLK_RIGHT:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftRight();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_LEFT:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftLeft();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_DOWN:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftDown();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_UP:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftUp();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_DELETE:
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->ClearCurrentTile();
                            else {
                                CurProject->SelectionRect->clear();
                                CurProject->SelectionRect->AssignSection();
                                CurProject->LevelMap->DrawMap();
                            }
			}
                        break;
                    case SDLK_ESCAPE:
                        quit = true; break;
                    case SDLK_RETURN:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetTileSelected();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case '=':
                    case '':
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SelectTileCur();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case SDLK_PAGEDOWN:
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->SelectedTileIncrID();
                            else {
                                CurProject->SelectionRect->IncrID();
                                CurProject->SelectionRect->AssignSection();
                                CurProject->LevelMap->DrawMap();
                            }
			}
                        break;
                    case SDLK_PAGEUP:
		        if (CurProject != NULL)
			{
                            if (!CurProject->SelectionRect->isActive()) CurProject->LevelMap->SelectedTileDecrID();
                            else {
                                CurProject->SelectionRect->DecrID();
                                CurProject->SelectionRect->AssignSection();
                                CurProject->LevelMap->DrawMap();
                            }
			}
                        break;
                    case SDLK_F1:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetPalCurrent(0);
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_F2:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetPalCurrent(1);
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_F3:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetPalCurrent(2);
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_F4:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->SetPalCurrent(3);
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_F5:
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->ToggleHighPriority();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case SDLK_F6:
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->ToggleLowPriority();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case SDLK_F9:
		        if (CurProject != NULL)
			{
                            CurProject->Save();
			}
			break;
                    case SDLK_F10: //redraw whole screen
		        if (CurProject != NULL)
			{
                            CurProject->Redraw();
			}
			break;
                    case SDLK_BACKSPACE:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->CurShiftLeft();
                            CurProject->LevelMap->ClearCurrentTile();
                            CurProject->SelectionRect->Unselect();
			}
			break;
                    case '[':
                    case '':
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->DecScreenOffset();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case '\'':
                    case '':
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->IncScreenOffset();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case ';':
                    case '':
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->DecScreenXOffset();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case '\\':
                    case '#':
                    case '+':
                    case ']':
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->IncScreenXOffset();
                            CurProject->LevelMap->DrawMap();
                            CurProject->SelectionRect->SelDrawRect();
			}
			break;
                    case SDLK_END:
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->IncSelOffset();
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_HOME:
		        if (CurProject != NULL)
			{
                            CurProject->GfxStuff->DecSelOffset();
                            CurProject->GfxStuff->DrawSelector();
			}
			break;
                    case SDLK_SPACE:
		        if (CurProject != NULL)
			{
                            CurProject->LevelMap->ClearCurrentTile();
                            CurProject->LevelMap->CurShiftRight();
			}
			break;
                    default:
                        if (event.key.keysym.sym >= 'a' && event.key.keysym.sym <= 'z') {
                            if (CtrlPress) {
                                switch(event.key.keysym.sym)
                                {
                                    case 'c':
				        if (CurProject != NULL)
					{
                                            if (CurProject->SelectionRect->isActive()) {
                                                if (CurProject->CopyRect != NULL) delete CurProject->CopyRect;
                                                CurProject->CopyRect = new SelRect(CurProject->SelectionRect);
                                            }
					}
                                        break;
                                    case 'x':
				        if (CurProject != NULL)
					{
                                            if (CurProject->SelectionRect->isActive()) {
                                                if (CurProject->CopyRect != NULL) delete CurProject->CopyRect;
                                                CurProject->CopyRect = new SelRect(CurProject->SelectionRect);
                                                CurProject->SelectionRect->clear();
                                                CurProject->SelectionRect->AssignSection();
                                                CurProject->LevelMap->DrawMap();
                                            }
					}
                                        break;
                                    case 'v':
				        if (CurProject != NULL)
					{
                                            CurProject->CopyRect->PasteSection();
                                            CurProject->LevelMap->DrawMap();
					}
                                        break;
                                    case 'a':
				        if (CurProject != NULL)
					{
                                            CurProject->SelectionRect->SelInit(0, 0);
                                            CurProject->SelectionRect->SelFinalize(CurProject->PrjData->map.xSize*8, CurProject->PrjData->map.ySize*8);
					}
                                        break;
                                }
                            } else {
				if (CurProject != NULL)
				{
                                    CurProject->LevelMap->SetCurrentTile(event.key.keysym.sym - 'a' + CurProject->GfxStuff->GetTileOffset() + CurProject->PrjData->letterOffset);
                                    CurProject->LevelMap->CurShiftRight();
                                    CurProject->SelectionRect->Unselect();
				}
                            }
                        }
                        else if (event.key.keysym.sym >= '0' && event.key.keysym.sym <= '9') {
			    if (CurProject != NULL)
			    {
                                CurProject->LevelMap->SetCurrentTile(event.key.keysym.sym - '0' + CurProject->GfxStuff->GetTileOffset() + CurProject->PrjData->numberOffset);
                                CurProject->LevelMap->CurShiftRight();
                                CurProject->SelectionRect->Unselect();
			    }
                        }
                }
            }
            if (event.type == SDL_KEYUP)
            {
                switch(event.key.keysym.sym)
                {
                    case SDLK_RCTRL:
                    case SDLK_LCTRL:
                        CtrlPress = false; break;
                }
            }

#ifdef _WIN32
            if (event.type == SDL_SYSWMEVENT)
	    {
		    WinAPI::HandleWindowsEvent(&event);
	    }
#endif

            MainScreen->ProcessDisplay();
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstring>
#include <fstream>

#include <SDL2/SDL.h>

#include "PrjHndl.h"
#include "TxtRead.h"
#include "Resource.h"

ProjectData::ProjectData(const char* const prjtxt) {
    tileOffset = 0;
    letterOffset = numberOffset = 0;

    FILE* prjfile = fopen(prjtxt, "r");
    if (prjfile == NULL) {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Please drag and drop your project file onto this program to start it.", NULL);
        exit(1);
    }

    while (!feof(prjfile)) {
        char line[256];
        fgets(line, 256, prjfile);
	infoType info_type = readInfoType(line);
	if (info_type != infoType::INVALID)
		AssignInfo(info_type, line+strcspn(line, ":")+1);
    }

    fclose(prjfile);
}

void ProjectData::AssignInfo(const infoType type, char* content) {
    switch(type) {
        case infoType::PALETTE_FILE:
		strcpy(pal.name, trimString(content));
		break;
        case infoType::MAPPING_FILE:
		strcpy(map.name, trimString(content));
		break;
        case infoType::ART_FILE:
		strcpy(art.name, trimString(content));
		break;
        case infoType::PALETTE_OFFSET:
		pal.offset = strtol(content, NULL, 0);
		break;
        case infoType::MAPPING_OFFSET:
		map.offset = strtol(content, NULL, 0);
		break;
        case infoType::ART_OFFSET:
		art.offset = strtol(content, NULL, 0);
		break;
        case infoType::PALETTE_LENGTH:
		pal.length = strtol(content, NULL, 0);
		break;
        case infoType::MAPPING_LENGTH:
		map.length = strtol(content, NULL, 0);
		break;
        case infoType::ART_LENGTH:
		art.length = strtol(content, NULL, 0);
		break;
        case infoType::PALETTE_COMPRESSION:
		pal.compression = readComprType(trimString(content));
		break;
        case infoType::MAPPING_COMPRESSION:
		map.compression = readComprType(trimString(content));
		break;
        case infoType::ART_COMPRESSION:
		art.compression = readComprType(trimString(content));
		break;
        case infoType::X_SIZE:
		map.xSize = strtol(content, NULL, 0);
		break;
        case infoType::Y_SIZE:
		map.ySize = strtol(content, NULL, 0);
		break;
        case infoType::TILE_OFFSET:
		tileOffset = strtol(content, NULL, 0);
		break;
        case infoType::LETTER_OFFSET:
		letterOffset = strtol(content, NULL, 0);
		break;
        case infoType::NUMBER_OFFSET:
		numberOffset = strtol(content, NULL, 0);
		break;
        case infoType::SAVE_FILE:
		strcpy(map.saveName, trimString(content));
		break;
        case infoType::KOSINSKI_MODULE_SIZE:
		art.kosinski_module_size = strtol(content, NULL, 0);
		break;
    }
}
<commit_msg>Making PrjHndl use a stream instead of fopen<commit_after>#include <cstring>
#include <fstream>

#include <SDL2/SDL.h>

#include "PrjHndl.h"
#include "TxtRead.h"
#include "Resource.h"

ProjectData::ProjectData(const char* const prjtxt) {
    tileOffset = 0;
    letterOffset = numberOffset = 0;

    std::ifstream prjfile(prjtxt, std::ios::in);
    if (!prjfile.is_open()) {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Please drag and drop your project file onto this program to start it.", NULL);
        exit(1);
    }

    while (!prjfile.eof()) {
        char line[256];
        prjfile.getline(line, 256);
	infoType info_type = readInfoType(line);
	if (info_type != infoType::INVALID)
		AssignInfo(info_type, line+strcspn(line, ":")+1);
    }
}

void ProjectData::AssignInfo(const infoType type, char* content) {
    switch(type) {
        case infoType::PALETTE_FILE:
		strcpy(pal.name, trimString(content));
		break;
        case infoType::MAPPING_FILE:
		strcpy(map.name, trimString(content));
		break;
        case infoType::ART_FILE:
		strcpy(art.name, trimString(content));
		break;
        case infoType::PALETTE_OFFSET:
		pal.offset = strtol(content, NULL, 0);
		break;
        case infoType::MAPPING_OFFSET:
		map.offset = strtol(content, NULL, 0);
		break;
        case infoType::ART_OFFSET:
		art.offset = strtol(content, NULL, 0);
		break;
        case infoType::PALETTE_LENGTH:
		pal.length = strtol(content, NULL, 0);
		break;
        case infoType::MAPPING_LENGTH:
		map.length = strtol(content, NULL, 0);
		break;
        case infoType::ART_LENGTH:
		art.length = strtol(content, NULL, 0);
		break;
        case infoType::PALETTE_COMPRESSION:
		pal.compression = readComprType(trimString(content));
		break;
        case infoType::MAPPING_COMPRESSION:
		map.compression = readComprType(trimString(content));
		break;
        case infoType::ART_COMPRESSION:
		art.compression = readComprType(trimString(content));
		break;
        case infoType::X_SIZE:
		map.xSize = strtol(content, NULL, 0);
		break;
        case infoType::Y_SIZE:
		map.ySize = strtol(content, NULL, 0);
		break;
        case infoType::TILE_OFFSET:
		tileOffset = strtol(content, NULL, 0);
		break;
        case infoType::LETTER_OFFSET:
		letterOffset = strtol(content, NULL, 0);
		break;
        case infoType::NUMBER_OFFSET:
		numberOffset = strtol(content, NULL, 0);
		break;
        case infoType::SAVE_FILE:
		strcpy(map.saveName, trimString(content));
		break;
        case infoType::KOSINSKI_MODULE_SIZE:
		art.kosinski_module_size = strtol(content, NULL, 0);
		break;
    }
}
<|endoftext|>


<commit_before>#ifndef ORM_BDD_HPP
#define ORM_BDD_HPP

#include "debug.hpp"

#include <string>
#include <unordered_map>
#include <vector>

/* Abstract class to deal with any database */

namespace orm
{
    class Query;
    class SQLObjectBase;
    template<typename T> class SQLObject;
    class VAttr;

    class Bdd
    {
        public:
            Bdd(const std::string& username,const std::string& pass,const std::string& bdd,const std::string& serveur,const std::string& port);

            Bdd(const Bdd&) = delete;
            Bdd& operator=(const Bdd&) = delete;

            virtual bool connect() = 0;
            virtual bool disconnect() = 0;

            /* manualy create  a query */
            virtual Query* query()= 0;
            virtual Query* query(const std::string&) = 0;
            virtual Query* query(std::string&&) = 0;

            /* manualy create  a query */
            virtual Query* prepareQuery(const std::string&) = 0;
            virtual Query* prepareQuery(std::string&&) = 0;

            /* The user defined default bdd to use */
            //static Bdd* Default;
            static Bdd& Default;

            //const std::string& operator[](const std::string& key);

            bool save(const std::string& table,int& pk,const std::vector<VAttr*>& attrs);
            bool update(const std::string& table,const int& pk,const std::vector<VAttr*>& attrs);
            bool del(const std::string& table,const int& pk);

            virtual std::string escape_colum(const std::string&);
            virtual std::string escape_value(const std::string&);

            std::string escape_value(const std::string& filter,const std::string&);

        protected:
            friend class Query;
            /* Info for connection */
            const std::string s_username;
            const std::string s_password;
            const std::string s_bdd_name;
            const std::string s_serveur;
            const std::string s_port;
            /* Operaters to use you must define:
             * "exact"
             * "iexact"
             * "contains"
             * "icontains"
             * "regex"
             * "iregex"
             * "gt"
             * "gte"
             * "lt"
             * "lte"
             * "startswith"
             * "endswith"
             * "istartswith"
             * "iendswith" */
            std::unordered_map<std::string,std::string> operators;
            /* Execute a query */
            virtual bool executeQuery(Query& query) = 0;
            virtual int getLastInsertPk() = 0;

    };
};

#endif
<commit_msg>move to protected some methodes<commit_after>#ifndef ORM_BDD_HPP
#define ORM_BDD_HPP

#include "debug.hpp"

#include <string>
#include <unordered_map>
#include <vector>

/* Abstract class to deal with any database */

namespace orm
{
    class Query;
    class SQLObjectBase;
    template<typename T> class SQLObject;
    class VAttr;

    class Bdd
    {
        public:
            Bdd(const std::string& username,const std::string& pass,const std::string& bdd,const std::string& serveur,const std::string& port);

            Bdd(const Bdd&) = delete;
            Bdd& operator=(const Bdd&) = delete;

            virtual bool connect() = 0;
            virtual bool disconnect() = 0;

            /* manualy create  a query */
            virtual Query* query()= 0;
            virtual Query* query(const std::string&) = 0;
            virtual Query* query(std::string&&) = 0;

            /* manualy create  a query */
            virtual Query* prepareQuery(const std::string&) = 0;
            virtual Query* prepareQuery(std::string&&) = 0;

            /* The user defined default bdd to use */
            //static Bdd* Default;
            static Bdd& Default;

            //const std::string& operator[](const std::string& key);

        protected:
            friend class Query;
            template<typename T> friend class SQLObject;
            /* Info for connection */
            const std::string s_username;
            const std::string s_password;
            const std::string s_bdd_name;
            const std::string s_serveur;
            const std::string s_port;
            /* Operaters to use you must define:
             * "exact"
             * "iexact"
             * "contains"
             * "icontains"
             * "regex"
             * "iregex"
             * "gt"
             * "gte"
             * "lt"
             * "lte"
             * "startswith"
             * "endswith"
             * "istartswith"
             * "iendswith" */
            std::unordered_map<std::string,std::string> operators;
            /* Execute a query */
            virtual bool executeQuery(Query& query) = 0;
            virtual int getLastInsertPk() = 0;

            bool save(const std::string& table,int& pk,const std::vector<VAttr*>& attrs);
            bool update(const std::string& table,const int& pk,const std::vector<VAttr*>& attrs);
            bool del(const std::string& table,const int& pk);

            virtual std::string escape_colum(const std::string&);
            virtual std::string escape_value(const std::string&);

            std::string escape_value(const std::string& filter,const std::string&);

    };
};

#endif
<|endoftext|>


<commit_before>// OTL.cpp : R\[ AvP[ṼGg |Cg`܂B
//
#include <iostream>
#include "stdafx.h"
#include "Object.h"
//class Test{ public:Test(); };
#include "Test.h"
#include "parser.h"
#include "scope.h"
using namespace lang;
int main(int argc, char* argv[])
{
	Init();
	Test test;
	parser pars;
	std::wstring text(L"1+1+1+1");
	pars.Parse(text);
	scope scop(&pars.root);
	auto ret = scop.Run();
	std::wcout << ret->ToString();
	return 0;
}

<commit_msg>TreeView<commit_after>// OTL.cpp : R\[ AvP[ṼGg |Cg`܂B
//
#include <iostream>
#include "stdafx.h"
#include "Object.h"
//class Test{ public:Test(); };
#include "Test.h"
#include "parser.h"
#include "scope.h"
using namespace lang;
void TreeView(TreeNode *tree, int sp)
{
	for (int i = 0; i < sp; i++)
	{
		std::cout << ((i == sp - 1) ? /*''*/(char)0x19 : (char)0x05/*''*/);
	}
	switch (tree->Type)
	{
		case NODE_ROOT:
			std::cout << "ROOT" << std::endl;
			TreeView(((RootNode*)tree)->Child, sp + 1);
			break;
		case NODE_EVAL:
			std::cout << "EVAL" << std::endl;
			TreeView(((EvalNode*)tree)->Child, sp + 1);
			break;
		case NODE_CONSTANT:
			std::wcout << L"CONSTANT " << ((ConstNode<ObjectBase*>*)tree)->constant->ToString() << std::endl;
			break;
		case NODE_OP:
			std::wcout << L"OP " << tree->Token->name << std::endl;
			TreeView(((BinOPNode*)tree)->Child[0], sp + 1);
			TreeView(((BinOPNode*)tree)->Child[1], sp + 1);
			break;
	}
}
int main(int argc, char* argv[])
{
	Init();
	Test test;
	parser pars;
	std::wstring text(L"1+1+1+1");
	pars.Parse(text);
	TreeView(&pars.root, 0);
	scope scop(&pars.root);
	auto ret = scop.Run();
	std::wcout << ret->ToString();
	return 0;
}

<|endoftext|>


<commit_before>/*

Mozzie - An MQTT plugin for the X-Plane flight simulator.
Copyright (C) 2017  Ben Russell - br@x-plugins.com

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 3 of the License, or
(at your option) any later version.

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

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

//
// Created by br on 28/01/17.
//

#include "Options.h"
#include "Mozzie.h"

#include <XPLMUtilities.h>
#include <sys/stat.h>

Options::Options( const std::string filename ){

    // Setup some sane default key values.
    _map_keyvals["client_name"] = "X-Plane/Mozzie";
    _map_keyvals["server_name"] = "localhost";
    _map_keyvals["server_port"] = "1883";

    // Read and parse...

    this->_destroy_raw_blob = false;

    FILE* fh = fopen( filename.c_str(), "rb" );
    if( fh ){

        size_t filesize=0;

        struct stat stat_info;
        int stat_ret = stat( filename.c_str(), &stat_info);

        if( -1 == stat_ret ) {
            //stat failed!

        }else {

            filesize = (size_t)stat_info.st_size;

        }

        char* blob = (char*)malloc( filesize );

        fread(
                blob,
                1,
                filesize,
                fh
            );

        this->_destroy_raw_blob = true;
        this->_raw_blob = new std::string( blob );

        free( blob );
        fclose( fh );

        // Parse the grud damn thing.

        std::vector<std::string> svLines = this->explode( *this->_raw_blob, '\n' );
        size_t line_count = svLines.size();
        for( size_t lx=0; lx < line_count; lx++ ){

            std::vector<std::string> svTokens = this->explode( svLines[lx], '=' );

            if( 2 == svTokens.size() ){
                std::string sKey = svTokens[0];
                std::string sVal = svTokens[1];

                this->_map_keyvals[ sKey ] = sVal;

                std::string sMsg = "Options: " + sKey + "=" + sVal + "\n";
                Mozzie::debug( sMsg.c_str() );

            }

        } //loop over all the lines in the file

    }else{

        Mozzie::debug("Options: Failed to read filename specified.\n"); //FIXME: Improve this.

    }

}

Options::~Options(){
    if( this->_destroy_raw_blob ){
        delete( this->_raw_blob );
    }

}

std::string Options::get( const std::string keyname ){

    std::map<std::string, std::string>::iterator it;

    it = _map_keyvals.find( keyname );
    if( _map_keyvals.end() != it ){
        return it->second;

    } // find options key:value pair and return valure.

    return "";

}

std::vector<std::string> Options::explode(std::string const & s, char delim)
{
    std::vector<std::string> result;
    std::istringstream iss(s);

    for (std::string token; std::getline(iss, token, delim); )
    {
        result.push_back(std::move(token));
    }

    return result;
}

//eof
<commit_msg>Options: Adds code to ignore comment lines that start with #. Adds code to create default mozzie_prefs.txt with sane defaults if the file does not exist.<commit_after>/*

Mozzie - An MQTT plugin for the X-Plane flight simulator.
Copyright (C) 2017  Ben Russell - br@x-plugins.com

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 3 of the License, or
(at your option) any later version.

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

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

//
// Created by br on 28/01/17.
//

#include "Options.h"
#include "Mozzie.h"

#include <XPLMUtilities.h>
#include <sys/stat.h>

Options::Options( const std::string filename ){

    // Setup some sane default key values.
    _map_keyvals["client_name"] = "X-Plane/Mozzie";
    _map_keyvals["server_name"] = "localhost";
    _map_keyvals["server_port"] = "1883";

    // Read and parse...

    this->_destroy_raw_blob = false;

    FILE* fh = fopen( filename.c_str(), "rb" );
    if( fh ){

        size_t filesize=0;

        struct stat stat_info;
        int stat_ret = stat( filename.c_str(), &stat_info);

        if( -1 == stat_ret ) {
            //stat failed!

        }else {

            filesize = (size_t)stat_info.st_size;

        }

        char* blob = (char*)malloc( filesize );

        fread(
                blob,
                1,
                filesize,
                fh
            );

        this->_destroy_raw_blob = true;
        this->_raw_blob = new std::string( blob );

        free( blob );
        fclose( fh );

        // Parse the grud damn thing.

        std::vector<std::string> svLines = this->explode( *this->_raw_blob, '\n' );
        size_t line_count = svLines.size();
        for( size_t lx=0; lx < line_count; lx++ ){

            std::vector<std::string> svTokens = this->explode( svLines[lx], '=' );

            if( 2 == svTokens.size() ){
                std::string sKey = svTokens[0];
                std::string sVal = svTokens[1];

                this->_map_keyvals[ sKey ] = sVal;

                //detect and ignore comments
                if( '#' != sKey[0] ){
                    std::string sMsg = "  " + sKey + "=" + sVal + "\n";
                    Mozzie::debug( sMsg.c_str() );
                } //if comment marker

            } //did the line split neatly into two items?

        } //loop over all the lines in the file

    }else{

        // No options file was located. Create a buffer, fill it with defaults, write it to disk.
        std::string sOptionsDefaults = "";

        sOptionsDefaults += "client_name=" + _map_keyvals["client_name"] + "\r\n";
        sOptionsDefaults += "server_name=" + _map_keyvals["server_name"] + "\r\n";
        sOptionsDefaults += "server_port=" + _map_keyvals["server_port"] + "\r\n";

        FILE* fh = fopen( filename.c_str(), "wb" );
        if( fh ){
            fwrite( sOptionsDefaults.c_str(), sOptionsDefaults.size(), 1, fh );
            fclose( fh );

            Mozzie::debug("Created default <XP>/mozzie_prefs.txt\r\n");

        }else{
            Mozzie::debug("ERROR: Could not create default <XP>/mozzie_prefs.txt\r\n");
        }

    }

}

Options::~Options(){
    if( this->_destroy_raw_blob ){
        delete( this->_raw_blob );
    }

}

std::string Options::get( const std::string keyname ){

    std::map<std::string, std::string>::iterator it;

    it = _map_keyvals.find( keyname );
    if( _map_keyvals.end() != it ){
        return it->second;

    } // find options key:value pair and return valure.

    return "";

}

std::vector<std::string> Options::explode(std::string const & s, char delim)
{
    std::vector<std::string> result;
    std::istringstream iss(s);

    for (std::string token; std::getline(iss, token, delim); )
    {
        result.push_back(std::move(token));
    }

    return result;
}

//eof
<|endoftext|>


<commit_before>#include "Physics.h"

int Physics::getBounceAngle()
{
  return this->bounceAngle;
}
<commit_msg>Delete Physics.cpp<commit_after><|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "Operation.h"
int VALID = 1000000;
int LEN = VALID / 8 + 2;

void test_carray() {
	unsigned long long *ptr = new unsigned long long[LEN];
	ptr[0] = 0;
	ptr[1] = 0xFFFFFFFFFF;
	Pi_carry(ptr);
	assert(ptr[0] == 0xFF && "carry error.");
	assert(ptr[1] == 0xFFFFFFFF && "carry error.");
	delete[] ptr;
}

void test_multiply_divide() {
	unsigned *ptr = new unsigned[LEN];
	for (int i = 0; i < LEN; i++)
		ptr[i] = i;
	unsigned num = 123454321;
	multiply(ptr, num);
	divide(ptr, num);
	for (int i = 0; i < LEN; i++)
		assert(ptr[i] == (unsigned)i && "multiply or divide error.");
	delete[] ptr;
}

void test_add_minus() {
	unsigned long long *ptr = new unsigned long long[LEN];
	unsigned *ptr2 = new unsigned[LEN];
	for (int i = 0; i < LEN; i++) {
		ptr[i] = LEN - i;
		ptr2[i] = ptr[i] + 1;
	}
	ptr[0] = 1, ptr2[0] = 0;

	minus(ptr, ptr2);
	assert(ptr[0] == 0 && "ptr[0] minus error.");
	assert(ptr[LEN - 1] == BASE - 1 && "ptr[LEN - 1] minus error.");
	for (int i = 1; i < LEN - 1; i++)
		assert(ptr[i] == BASE - 2 && "substraction error.");

	add(ptr, ptr2);
	assert(ptr[0] == 1 && "ptr[0] add error.");
	for (int i = 1; i < LEN; i++)
		assert(ptr[i] == (unsigned)LEN - i && "addition error.");
	delete[] ptr;
	delete[] ptr2;
}

void test_shift_right() {
	unsigned *sub = new unsigned[LEN];
	for (int i = 0; i < LEN; i++)
		sub[i] = 0xFFFFFFFF;
	shift_right(sub, sizeof(unsigned) * 8 * (LEN - 1) + 6);
	assert(sub[LEN - 1] == 0x3FFFFFF && "shift error.");
	for (int i = 0; i < LEN - 1; i++)
		assert(sub[i] == 0 && "shift error.");

	for (int i = 0; i < LEN; i++)
		sub[i] = 0xABCDDCBE;
	shift_right(sub, sizeof(unsigned) * 8 * (LEN - 2) + 4);
	assert(sub[LEN - 2] == 0xABCDDCB && "shift error.");
	assert(sub[LEN - 1] == 0xEABCDDCB  && "shift error.");
	for (int i = 0; i < LEN - 2; i++)
		assert(sub[i] == 0 && "shift error.");

	sub[0] = 0;
	sub[1] = 0x19999999;
	sub[2] = 0x99999999;
	shift_right(sub, 8);
	assert(sub[1] == 0x00199999 && "shift error!");
	assert(sub[2] == 0x99999999 && "shift error!");
	delete[] sub;
}

void test_print() {
	unsigned tmp = 180150013;
	print(tmp);
}

int main(int argc, char *argv[]) {
	test_add_minus();
	test_multiply_divide();
	test_print();
	test_shift_right();
	test_carray();
	return 0;
}
<commit_msg>fix small bug<commit_after>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "Operation.h"
int VALID = 1000000;
int LEN = VALID / 8 + 2;

void test_carray() {
	unsigned long long *ptr = new unsigned long long[LEN];
	ptr[0] = 0;
	ptr[1] = 0xFFFFFFFFFF;
	Pi_carry(ptr);
	assert(ptr[0] == 0xFF && "carry error.");
	assert(ptr[1] == 0xFFFFFFFF && "carry error.");
	delete[] ptr;
}

void test_multiply_divide() {
	unsigned *ptr = new unsigned[LEN];
	for (int i = 0; i < LEN; i++)
		ptr[i] = i;
	unsigned num = 123454321;
	multiply(ptr, num);
	divide(ptr, num);
	for (int i = 0; i < LEN; i++)
		assert(ptr[i] == (unsigned)i && "multiply or divide error.");
	delete[] ptr;
}

void test_add_minus() {
	unsigned long long *ptr = new unsigned long long[LEN];
	unsigned *ptr2 = new unsigned[LEN];
	for (int i = 0; i < LEN; i++) {
		ptr[i] = LEN - i;
		ptr2[i] = ptr[i] + 1;
	}
	ptr[0] = 1, ptr2[0] = 0;

	minus(ptr, ptr2);
	assert(ptr[0] == 0 && "ptr[0] minus error.");
	assert(ptr[LEN - 1] == BASE - 1 && "ptr[LEN - 1] minus error.");
	for (int i = 1; i < LEN - 1; i++)
		assert(ptr[i] == BASE - 2 && "substraction error.");

	add(ptr, ptr2);
	assert(ptr[0] == 1 && "ptr[0] add error.");
	for (int i = 1; i < LEN; i++)
		assert(ptr[i] == (unsigned)LEN - i && "addition error.");
	delete[] ptr;
	delete[] ptr2;
}

void test_shift_right() {
	unsigned *sub = new unsigned[LEN];
	for (int i = 0; i < LEN; i++)
		sub[i] = 0xFFFFFFFF;
	shift_right(sub, sizeof(unsigned) * 8 * (LEN - 1) + 6);
	assert(sub[LEN - 1] == 0x3FFFFFF && "shift error.");
	for (int i = 0; i < LEN - 1; i++)
		assert(sub[i] == 0 && "shift error.");

	for (int i = 0; i < LEN; i++)
		sub[i] = 0xABCDDCBE;
	shift_right(sub, sizeof(unsigned) * 8 * (LEN - 2) + 4);
	assert(sub[LEN - 2] == 0xABCDDCB && "shift error.");
	assert(sub[LEN - 1] == 0xEABCDDCB  && "shift error.");
	for (int i = 0; i < LEN - 2; i++)
		assert(sub[i] == 0 && "shift error.");

	sub[0] = 0;
	sub[1] = 0x19999999;
	sub[2] = 0x99999999;
	shift_right(sub, 8);
	assert(sub[1] == 0x00199999 && "shift error!");
	assert(sub[2] == 0x99999999 && "shift error!");
	delete[] sub;
}

int main(int argc, char *argv[]) {
	test_add_minus();
	test_multiply_divide();
	test_shift_right();
	test_carray();
	return 0;
}
<|endoftext|>


<commit_before>// Assignment 8 - COSC 1410
// TA: Can Cao
// Author: Micah Thomas
#include <cstdio>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>

using namespace std;

ifstream inStream;

struct student
{
    int id;
    char fname[20];
    char lname[20];
    char email[40];
    double gpa;
};

struct roster
{
    student records[100];
    int students;
};

bool getRecord(int& recNum, int& id, char fname[], char lname[], char email[], double& gpa);
void loadData(struct roster &data);
void printData(struct roster data);
void printStudent(struct student data);
int searchId(struct roster data);
int searchName(struct roster data);
bool menu(struct roster data);

int main() {
    bool loop;
    roster compsci;
    loadData(compsci);
    do {
        loop = menu(compsci);
    } while(loop);
}

bool getRecord(int& recNum, int& id, char fname[], char lname[], char email[], double& gpa){
   if (recNum==0) {
      inStream.open("prog8in.txt");
      if (inStream.fail()){
         cout<<"File \"prog8in.txt\" cannot be opened."<<endl;
         cout<<"Press ENTER to continue ...";
         cin.get();
         return false;
      } else cout<<"File \"prog8in.txt\" opened."<<endl;
   }
   inStream >>id >>fname >>lname >>email >>gpa;
   if (inStream.eof()) return false;
   else {
       recNum++;
       return true;
   }
}

void loadData(struct roster &data)
{
    data.students = 0;
    int recNum = 0;
    int id;
    char fname[20];
    char lname[20];
    char email[40];
    double gpa;
    while(getRecord(recNum, id, fname, lname, email, gpa))
    {
        data.records[data.students].id    = id;
        strcpy(data.records[data.students].fname, fname);
        strcpy(data.records[data.students].lname, lname);
        strcpy(data.records[data.students].email, email);
        data.records[data.students].gpa   = gpa;
        data.students = recNum;
    }
    printData(data);
    cout << "\n\n";
}

void printData(struct roster data)
{
    for (int i=0; i < data.students; i++) {
        cout << "\n\nStudent[" << i << "]";
        printStudent(data.records[i]);
    }
}

void printStudent(struct student data)
{
    cout << "\nID:\t\t" << data.id;
    cout << "\nFIRST NAME:\t" << data.fname;
    cout << "\nLAST NAME:\t" << data.lname;
    cout << "\nEMAIL:\t\t" << data.email;
    cout << "\nGPA:\t\t" << data.gpa;
}

int searchId(struct roster data)
{
    int id;
    cout << "Search for student with ID: ";
    cin  >> id;
    for (int i=0; i < data.students; i++)
    {
        if (data.records[i].id == id)
            return i;
    }
    cout << "Couldn't find id in Data";
    return -1;
}

int searchLName(struct roster data)
{
    char lname[20];
    cout << "Search for student with Last Name: ";
    cin  >> lname;
    for (int i=0; i < data.students; i++)
    {
        if(strcmp(data.records[i].lname, lname) == 0)
            return i;
    }
    cout << "Couldn't find id in Data";
    return -1;
}

bool menu(struct roster data)
{
    int choice, id;
    cout << "\n********** Class Roster **********\nTotal Students = " << data.students;
    cout << "\n1. Display all students";
    cout << "\n2. Search a student by ID";
    cout << "\n3. Search a student by Last Name";
    cout << "\n4. Exit";
    cout << "\n>> ";
    cin >> choice;
    switch (choice) {
        case 1:
        cout << "\n\nShowing Records:";
        printData(data);
        break;
        case 2:
        id = searchId(data);
        if (id != -1)
            printStudent(data.records[id]);
        break;
        case 3:
        id = searchLName(data);
        if (id != -1)
            printStudent(data.records[id]);
        break;
        case 4:
        return false;
        break;
        default:
        return false;
        break;
    }
    return true;
}<commit_msg>Changed Error Message<commit_after>// Assignment 8 - COSC 1410
// TA: Can Cao
// Author: Micah Thomas
#include <cstdio>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>

using namespace std;

ifstream inStream;

struct student
{
    int id;
    char fname[20];
    char lname[20];
    char email[40];
    double gpa;
};

struct roster
{
    student records[100];
    int students;
};

bool getRecord(int& recNum, int& id, char fname[], char lname[], char email[], double& gpa);
void loadData(struct roster &data);
void printData(struct roster data);
void printStudent(struct student data);
int searchId(struct roster data);
int searchName(struct roster data);
bool menu(struct roster data);

int main() {
    bool loop;
    roster compsci;
    loadData(compsci);
    do {
        loop = menu(compsci);
    } while(loop);
}

bool getRecord(int& recNum, int& id, char fname[], char lname[], char email[], double& gpa){
   if (recNum==0) {
      inStream.open("prog8in.txt");
      if (inStream.fail()){
         cout<<"File \"prog8in.txt\" cannot be opened."<<endl;
         cout<<"Press ENTER to continue ...";
         cin.get();
         return false;
      } else cout<<"File \"prog8in.txt\" opened."<<endl;
   }
   inStream >>id >>fname >>lname >>email >>gpa;
   if (inStream.eof()) return false;
   else {
       recNum++;
       return true;
   }
}

void loadData(struct roster &data)
{
    data.students = 0;
    int recNum = 0;
    int id;
    char fname[20];
    char lname[20];
    char email[40];
    double gpa;
    while(getRecord(recNum, id, fname, lname, email, gpa))
    {
        data.records[data.students].id    = id;
        strcpy(data.records[data.students].fname, fname);
        strcpy(data.records[data.students].lname, lname);
        strcpy(data.records[data.students].email, email);
        data.records[data.students].gpa   = gpa;
        data.students = recNum;
    }
    printData(data);
    cout << "\n\n";
}

void printData(struct roster data)
{
    for (int i=0; i < data.students; i++) {
        cout << "\n\nStudent[" << i << "]";
        printStudent(data.records[i]);
    }
}

void printStudent(struct student data)
{
    cout << "\nID:\t\t" << data.id;
    cout << "\nFIRST NAME:\t" << data.fname;
    cout << "\nLAST NAME:\t" << data.lname;
    cout << "\nEMAIL:\t\t" << data.email;
    cout << "\nGPA:\t\t" << data.gpa;
}

int searchId(struct roster data)
{
    int id;
    cout << "Search for student with ID: ";
    cin  >> id;
    for (int i=0; i < data.students; i++)
    {
        if (data.records[i].id == id)
            return i;
    }
    cout << "Couldn't find ID: "<< id;
    return -1;
}

int searchLName(struct roster data)
{
    char lname[20];
    cout << "Search for student with Last Name: ";
    cin  >> lname;
    for (int i=0; i < data.students; i++)
    {
        if(strcmp(data.records[i].lname, lname) == 0)
            return i;
    }
    cout << "Couldn't find Last Name: "<< lname;
    return -1;
}

bool menu(struct roster data)
{
    int choice, id;
    cout << "\n********** Class Roster **********\nTotal Students = " << data.students;
    cout << "\n1. Display all students";
    cout << "\n2. Search a student by ID";
    cout << "\n3. Search a student by Last Name";
    cout << "\n4. Exit";
    cout << "\n>> ";
    cin >> choice;
    switch (choice) {
        case 1:
        cout << "\n\nShowing Records:";
        printData(data);
        break;
        case 2:
        id = searchId(data);
        if (id != -1)
            printStudent(data.records[id]);
        break;
        case 3:
        id = searchLName(data);
        if (id != -1)
            printStudent(data.records[id]);
        break;
        case 4:
        return false;
        break;
        default:
        return false;
        break;
    }
    return true;
}<|endoftext|>