<commit_before>#ifndef ATL_PARSER_HPP
#define ATL_PARSER_HPP
/**
 * @file /home/ryan/programming/atl/parser.hpp
 * @author Ryan Domigan <ryan_domigan@sutdents@uml.edu>
 * Created on Jun 29, 2013
 */

#include <iterator>
#include <sstream>

#include <string>
#include <vector>
#include <iostream>
#include <functional>

#include <iterator>

#include "./exception.hpp"
#include "./type.hpp"
#include "./conversion.hpp"
#include "./type_testing.hpp"
#include "./helpers.hpp"
#include "./print.hpp"

namespace atl
{
    // A simple minded parser, this just transforms a string into an Ast.  There are a couple of reserved symbols:
    //   '(' ')'         : Open and close an Ast branch
    //   DELIM '\\' DELIM : After much debate, I'm making Lambda a reserved word.  In principle, I'd like everything to be a
    //                     usable symbol at local scope.  This may still change (should I be able to do something like
    //                     `(def foo \ )  ((foo (a b) (+ a b)) 1 2)`)?
    //   DELIM 'let' DELIM: Simalar to lambda, if I'm going to getting Hindly Milner with polymorphic let is going to be much easier
    //                      If I can get a tagged type.
    //   DELIM '\''      : 'n expands to (quote n) (should probably be a macro).  Can still be used as part of a variable name (ie x and x' are both
    //                     valid symbols).
    //   '\"'            : starts and ends a string literal
    //   DELIM 0..9 DELIM: a number (a number must be all digits ie 124567, possibly with a decimal point.  If there is a non-digit ie 12345a, it
    //                     is a symbol.  hex/octal/binary representations are not a thing ATM).
    class ParseString
    {
    private:

	template<class Itr>
	void skip_ws_and_comments(Itr &itr, Itr const& end)
	{
		for(; itr != end; ++itr)
			{
				if(*itr == ';')
					for(; (itr != end) && (*itr != '\n'); ++itr);
				else if(!std::isspace(*itr))
					return;

				if(*itr == '\n')
					++_line;
			}
	}

	GC &_gc;
	unsigned long _line;

	static const string delim;	/* symbol deliminator */
	static const string _ws; 	/* white space */
	string scratch;

	inline bool digit(char c) { return ((c >= '0') && (c <= '9')); }
	bool string_is_number(const string& str) {
	    return (digit(str[0]) || ((str[0] == '-') && (str.length() > 1) && digit(str[1])));
	}

	template<class Itr>
	void parse(memory_pool::DynamicVector &vec, Itr &&itr, Itr &&end) {
	    for(; itr != end; ++itr) {
		switch(*itr)
                    {
                    case '\n':
                        ++_line;
                    case ' ':		/* whitespace */
                    case '\t':
                        continue;

                    case ';': 		/* comment */
                        for(; itr != end && *itr != '\n'; ++itr);
                        if(*itr == '\n') ++_line;
                        continue;

                    case '\'':
                        {		/* quote */
                            auto quote = vec.push_seq<Ast>();
                            vec[0] = wrap<Quote>();
                            ++vec;

                            ++itr;
                            parse(vec, itr, end);
                            quote->end_at(vec.end());
                            return;
                        }

                    case '(':
                        {		/* sub expression */
                            ++itr;
                            if(*itr == ')') {
                                auto null = vec.push_seq<Ast>();
                                null->end_at(vec.end());
                                return;
                            }

                            auto ast = vec.push_seq<Ast>();
                            while(*itr != ')')
                                {
                                    if(itr == end)
                                        throw UnbalancedParens
                                            (to_string(_line)
                                             .append(": error: unbalanced parens"));
                                    parse(vec, itr, end);
                                }

                            ++itr;
                            ast->end_at(vec.end());
                            return;
                        }

                    case ')': return;

                    case '"':
                        {		/* string */
                            std::string *str = reinterpret_cast<std::string*>(_gc.make<String>());

                            for(++itr; *itr != '"'; ++itr)
                                {
                                    if(itr == end) throw to_string(_line)
                                                       .append("string not terminated.");
                                    if(*itr == '\n') ++_line;

                                    str->push_back(*itr);
                                }

                            ++itr;
                            vec[0] = Any(tag<String>::value, str);
                            ++vec;
                            return;
                        }

                    default:
                        {
                            scratch.clear();

                            for(; (itr != end) && (delim.find(*itr) == string::npos); ++itr)
                                scratch.push_back(*itr);

                            if((itr != end) && (*itr == '\n')) ++_line;

                            if(string_is_number(scratch))
                                {
                                    vec[0] = wrap( atoi(scratch.c_str()) );
                                }
                            else if(scratch == "\\") // Lambda
                                {
                                    vec[0] = wrap<Lambda>();
                                }
                            else if(scratch == "let")
                                {
                                    vec[0] = wrap<Let>();
                                }
                            else
                                {
                                    vec[0] = _gc.amake<Symbol>(scratch);
                                }

                            ++vec;
                            return;
                        }
                    }
            }
	    return;
	}

    public:
	ParseString(GC &gc) : _gc(gc) {
	    _line = 1;
	    //_gc.mark_callback( [this](GC &gc) { _gc.mark(_mark); });
	}

	/* parse one S-expression from a string into an ast */
	Any& string_(const std::string& input) {
	    auto vec = _gc.dynamic_seq();
	    **vec = nil<Null>::value();

	    auto itr = input.begin(),
		    end = input.end();
	    parse(*vec, itr, end);

	    // Check that there was just one expression in our string
	    while(itr != input.end() && std::isspace(*itr)) ++itr;
	    if(itr != input.end())
		    throw MultiExpressionString(std::string("More than one expression in `")
		                                .append(input)
		                                .append("`"));

	    return *vec->begin();
	}

	/* parse one S-expression from a stream into an ast */
	Any& stream(istream &stream) {
	    auto initial_flags = stream.flags();
	    noskipws(stream);

	    auto vec = _gc.dynamic_seq();
	    **vec = nil<Null>::value();

	    auto itr = istreambuf_iterator<char>(stream),
		    end = istreambuf_iterator<char>();
	    parse(*vec, itr, end);

	    // Swallow any following whitepace or comments so the caller
	    // of the parser doesn't have to check.
	    skip_ws_and_comments(itr, end);

	    stream.flags(initial_flags);
	    return *vec->begin();
	}

	void reset_line_number() { _line = 1; }
    };
    const std::string ParseString::_ws = " \n\t";
    const std::string ParseString::delim = "()\" \n\t";
}
#endif
<commit_msg>Cleanup ParseString docs<commit_after>#ifndef ATL_PARSER_HPP
#define ATL_PARSER_HPP
/**
 * @file /home/ryan/programming/atl/parser.hpp
 * @author Ryan Domigan <ryan_domigan@sutdents@uml.edu>
 * Created on Jun 29, 2013
 */

#include <iterator>
#include <sstream>

#include <string>
#include <vector>
#include <iostream>
#include <functional>

#include <iterator>

#include "./exception.hpp"
#include "./type.hpp"
#include "./conversion.hpp"
#include "./type_testing.hpp"
#include "./helpers.hpp"
#include "./print.hpp"

namespace atl
{
    // A simple minded parser, this just transforms a string into an
    // Ast.  There are a couple of reserved symbols:
    //
    //   '(' ')'         : Open and close an Ast branch
    //
    //   DELIM '\\' DELIM : After much debate, I'm making Lambda a
    //                     reserved word.  In principle, I'd like
    //                     everything to be a usable symbol at local
    //                     scope.  This may still change (should I be
    //                     able to do something like `(def foo \ )
    //                     ((foo (a b) (+ a b)) 1 2)`)?
    //
    //   DELIM '\'' : 'n expands to (quote n) (should probably be a
    //                 macro).  Can still be used as part of a
    //                 variable name (ie x and x' are both valid
    //                 symbols).
    //
    //   '\"' : starts and ends a string literal
	//
    //   DELIM 0..9 DELIM: a number (a number must be all digits ie
    //                     124567, possibly with a decimal point.  If
    //                     there is a non-digit ie 12345a, it is a
    //                     symbol.  hex/octal/binary representations
    //                     are not a thing ATM).
	//  ';' : comments out to the end of line
    class ParseString
    {
    private:

	template<class Itr>
	void skip_ws_and_comments(Itr &itr, Itr const& end)
	{
		for(; itr != end; ++itr)
			{
				if(*itr == ';')
					for(; (itr != end) && (*itr != '\n'); ++itr);
				else if(!std::isspace(*itr))
					return;

				if(*itr == '\n')
					++_line;
			}
	}

	GC &_gc;
	unsigned long _line;

	static const string delim;	/* symbol deliminator */
	static const string _ws; 	/* white space */
	string scratch;

	inline bool digit(char c) { return ((c >= '0') && (c <= '9')); }
	bool string_is_number(const string& str) {
	    return (digit(str[0]) || ((str[0] == '-') && (str.length() > 1) && digit(str[1])));
	}

	template<class Itr>
	void parse(memory_pool::DynamicVector &vec, Itr &&itr, Itr &&end) {
	    for(; itr != end; ++itr) {
		switch(*itr)
                    {
                    case '\n':
                        ++_line;
                    case ' ':		/* whitespace */
                    case '\t':
                        continue;

                    case ';': 		/* comment */
                        for(; itr != end && *itr != '\n'; ++itr);
                        if(*itr == '\n') ++_line;
                        continue;

                    case '\'':
                        {		/* quote */
                            auto quote = vec.push_seq<Ast>();
                            vec[0] = wrap<Quote>();
                            ++vec;

                            ++itr;
                            parse(vec, itr, end);
                            quote->end_at(vec.end());
                            return;
                        }

                    case '(':
                        {		/* sub expression */
                            ++itr;
                            if(*itr == ')') {
                                auto null = vec.push_seq<Ast>();
                                null->end_at(vec.end());
                                return;
                            }

                            auto ast = vec.push_seq<Ast>();
                            while(*itr != ')')
                                {
                                    if(itr == end)
                                        throw UnbalancedParens
                                            (to_string(_line)
                                             .append(": error: unbalanced parens"));
                                    parse(vec, itr, end);
                                }

                            ++itr;
                            ast->end_at(vec.end());
                            return;
                        }

                    case ')': return;

                    case '"':
                        {		/* string */
                            std::string *str = reinterpret_cast<std::string*>(_gc.make<String>());

                            for(++itr; *itr != '"'; ++itr)
                                {
                                    if(itr == end) throw to_string(_line)
                                                       .append("string not terminated.");
                                    if(*itr == '\n') ++_line;

                                    str->push_back(*itr);
                                }

                            ++itr;
                            vec[0] = Any(tag<String>::value, str);
                            ++vec;
                            return;
                        }

                    default:
                        {
                            scratch.clear();

                            for(; (itr != end) && (delim.find(*itr) == string::npos); ++itr)
                                scratch.push_back(*itr);

                            if((itr != end) && (*itr == '\n')) ++_line;

                            if(string_is_number(scratch))
                                {
                                    vec[0] = wrap( atoi(scratch.c_str()) );
                                }
                            else if(scratch == "\\") // Lambda
                                {
                                    vec[0] = wrap<Lambda>();
                                }
                            else if(scratch == "let")
                                {
                                    vec[0] = wrap<Let>();
                                }
                            else
                                {
                                    vec[0] = _gc.amake<Symbol>(scratch);
                                }

                            ++vec;
                            return;
                        }
                    }
            }
	    return;
	}

    public:
	ParseString(GC &gc) : _gc(gc) {
	    _line = 1;
	    //_gc.mark_callback( [this](GC &gc) { _gc.mark(_mark); });
	}

	/* parse one S-expression from a string into an ast */
	Any& string_(const std::string& input) {
	    auto vec = _gc.dynamic_seq();
	    **vec = nil<Null>::value();

	    auto itr = input.begin(),
		    end = input.end();
	    parse(*vec, itr, end);

	    // Check that there was just one expression in our string
	    while(itr != input.end() && std::isspace(*itr)) ++itr;
	    if(itr != input.end())
		    throw MultiExpressionString(std::string("More than one expression in `")
		                                .append(input)
		                                .append("`"));

	    return *vec->begin();
	}

	/* parse one S-expression from a stream into an ast */
	Any& stream(istream &stream) {
	    auto initial_flags = stream.flags();
	    noskipws(stream);

	    auto vec = _gc.dynamic_seq();
	    **vec = nil<Null>::value();

	    auto itr = istreambuf_iterator<char>(stream),
		    end = istreambuf_iterator<char>();
	    parse(*vec, itr, end);

	    // Swallow any following whitepace or comments so the caller
	    // of the parser doesn't have to check.
	    skip_ws_and_comments(itr, end);

	    stream.flags(initial_flags);
	    return *vec->begin();
	}

	void reset_line_number() { _line = 1; }
    };
    const std::string ParseString::_ws = " \n\t";
    const std::string ParseString::delim = "()\" \n\t";
}
#endif
<|endoftext|>


<commit_before>/* ------------------------------------------------------------------
 * Copyright (C) 2009 Martin Storsjo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */

#include "wavreader.h"

#define TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))

uint32_t WavReader::readTag() {
	uint32_t tag = 0;
	tag = (tag << 8) | fgetc(wav);
	tag = (tag << 8) | fgetc(wav);
	tag = (tag << 8) | fgetc(wav);
	tag = (tag << 8) | fgetc(wav);
	return tag;
}

uint32_t WavReader::readInt32() {
	uint32_t value = 0;
	value |= fgetc(wav) <<  0;
	value |= fgetc(wav) <<  8;
	value |= fgetc(wav) << 16;
	value |= fgetc(wav) << 24;
	return value;
}

uint16_t WavReader::readInt16() {
	uint16_t value = 0;
	value |= fgetc(wav) << 0;
	value |= fgetc(wav) << 8;
	return value;
}

WavReader::WavReader(const char *filename) {
	dataLength = 0;
	format = 0;
	sampleRate = 0;
	bitsPerSample = 0;
	channels = 0;
	byteRate = 0;
	blockAlign = 0;

	wav = fopen(filename, "rb");
	if (wav == NULL)
		return;

	long dataPos = 0;
	while (true) {
		uint32_t tag = readTag();
		if (feof(wav))
			break;
		uint32_t length = readInt32();
		if (tag != TAG('R', 'I', 'F', 'F') || length < 4) {
			fseek(wav, length, SEEK_CUR);
			continue;
		}
		uint32_t tag2 = readTag();
		if (tag2 != TAG('W', 'A', 'V', 'E')) {
			length -= 4;
			fseek(wav, length, SEEK_CUR);
			continue;
		}
		// RIFF chunk found, iterate through it
		while (length >= 8) {
			uint32_t subtag = readTag();
			if (feof(wav))
				break;
			uint32_t sublength = readInt32();
			length -= 8;
			if (length < sublength)
				break;
			if (subtag == TAG('f', 'm', 't', ' ')) {
				if (sublength < 16) {
					// Insufficient data for 'fmt '
					break;
				}
				format = readInt16();
				channels = readInt16();
				sampleRate = readInt32();
				byteRate = readInt32();
				blockAlign = readInt16();
				bitsPerSample = readInt16();
			} else if (subtag == TAG('d', 'a', 't', 'a')) {
				dataPos = ftell(wav);
				dataLength = sublength;
			} else {
				fseek(wav, sublength, SEEK_CUR);
			}
			length -= sublength;
		}
		if (length > 0) {
			// Bad chunk?
			fseek(wav, length, SEEK_CUR);
		}
	}
	fseek(wav, dataPos, SEEK_SET);
}

WavReader::~WavReader() {
	fclose(wav);
}

bool WavReader::getHeader(int* format, int* channels, int* sampleRate, int* bitsPerSample, unsigned int* dataLength) {
	if (format)
		*format = this->format;
	if (channels)
		*channels = this->channels;
	if (sampleRate)
		*sampleRate = this->sampleRate;
	if (bitsPerSample)
		*bitsPerSample = this->bitsPerSample;
	if (dataLength)
		*dataLength = this->dataLength;
	return format && sampleRate;
}

int WavReader::readData(unsigned char* data, unsigned int length) {
	if (wav == NULL)
		return -1;
	if (length > dataLength)
		length = dataLength;
	int n = fread(data, 1, length, wav);
	dataLength -= length;
	return n;
}

<commit_msg>Seek past the wave data while parsing subtags<commit_after>/* ------------------------------------------------------------------
 * Copyright (C) 2009 Martin Storsjo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */

#include "wavreader.h"

#define TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))

uint32_t WavReader::readTag() {
	uint32_t tag = 0;
	tag = (tag << 8) | fgetc(wav);
	tag = (tag << 8) | fgetc(wav);
	tag = (tag << 8) | fgetc(wav);
	tag = (tag << 8) | fgetc(wav);
	return tag;
}

uint32_t WavReader::readInt32() {
	uint32_t value = 0;
	value |= fgetc(wav) <<  0;
	value |= fgetc(wav) <<  8;
	value |= fgetc(wav) << 16;
	value |= fgetc(wav) << 24;
	return value;
}

uint16_t WavReader::readInt16() {
	uint16_t value = 0;
	value |= fgetc(wav) << 0;
	value |= fgetc(wav) << 8;
	return value;
}

WavReader::WavReader(const char *filename) {
	dataLength = 0;
	format = 0;
	sampleRate = 0;
	bitsPerSample = 0;
	channels = 0;
	byteRate = 0;
	blockAlign = 0;

	wav = fopen(filename, "rb");
	if (wav == NULL)
		return;

	long dataPos = 0;
	while (true) {
		uint32_t tag = readTag();
		if (feof(wav))
			break;
		uint32_t length = readInt32();
		if (tag != TAG('R', 'I', 'F', 'F') || length < 4) {
			fseek(wav, length, SEEK_CUR);
			continue;
		}
		uint32_t tag2 = readTag();
		if (tag2 != TAG('W', 'A', 'V', 'E')) {
			length -= 4;
			fseek(wav, length, SEEK_CUR);
			continue;
		}
		// RIFF chunk found, iterate through it
		while (length >= 8) {
			uint32_t subtag = readTag();
			if (feof(wav))
				break;
			uint32_t sublength = readInt32();
			length -= 8;
			if (length < sublength)
				break;
			if (subtag == TAG('f', 'm', 't', ' ')) {
				if (sublength < 16) {
					// Insufficient data for 'fmt '
					break;
				}
				format = readInt16();
				channels = readInt16();
				sampleRate = readInt32();
				byteRate = readInt32();
				blockAlign = readInt16();
				bitsPerSample = readInt16();
			} else if (subtag == TAG('d', 'a', 't', 'a')) {
				dataPos = ftell(wav);
				dataLength = sublength;
				fseek(wav, sublength, SEEK_CUR);
			} else {
				fseek(wav, sublength, SEEK_CUR);
			}
			length -= sublength;
		}
		if (length > 0) {
			// Bad chunk?
			fseek(wav, length, SEEK_CUR);
		}
	}
	fseek(wav, dataPos, SEEK_SET);
}

WavReader::~WavReader() {
	fclose(wav);
}

bool WavReader::getHeader(int* format, int* channels, int* sampleRate, int* bitsPerSample, unsigned int* dataLength) {
	if (format)
		*format = this->format;
	if (channels)
		*channels = this->channels;
	if (sampleRate)
		*sampleRate = this->sampleRate;
	if (bitsPerSample)
		*bitsPerSample = this->bitsPerSample;
	if (dataLength)
		*dataLength = this->dataLength;
	return format && sampleRate;
}

int WavReader::readData(unsigned char* data, unsigned int length) {
	if (wav == NULL)
		return -1;
	if (length > dataLength)
		length = dataLength;
	int n = fread(data, 1, length, wav);
	dataLength -= length;
	return n;
}

<|endoftext|>


<commit_before><commit_msg>drawingml export: fix EllipseShape for docx<commit_after><|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2017 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <map>
#include <common.cxx>
#include <nic_mock.hpp>
#include <net/inet4.hpp>

int ip_packets_dropped = 0;
int ip_packets_received = 0;

net::IP4::Drop_reason last_drop_reason;
net::IP4::Direction last_drop_direction;

std::map<net::IP4::Drop_reason, std::string> drop_reasons {
  {net::IP4::Drop_reason::Bad_source, "Bad source address"},
  {net::IP4::Drop_reason::Bad_destination, "Bad destination address"},
  {net::IP4::Drop_reason::Wrong_version, "Wrong version"},
  {net::IP4::Drop_reason::Wrong_checksum, "Wrong checksum"},
  {net::IP4::Drop_reason::Unknown_proto, "Unknown proto"},
  {net::IP4::Drop_reason::TTL0, "TTL 0"}
};

std::map<net::Protocol, int> pass_count {
  {net::Protocol::UDP, 0},
  {net::Protocol::TCP, 0},
  {net::Protocol::ICMPv4, 0}
};

#define MYINFO(X,...) INFO("Unit IP4", X, ##__VA_ARGS__)

void ip_rcv_udp(net::Packet_ptr) {
  MYINFO("UDP got packet from IP");

  pass_count[net::Protocol::UDP]++;
}

void ip_rcv_tcp(net::Packet_ptr) {
  MYINFO("TCP got packet from IP");

  pass_count[net::Protocol::TCP]++;
}

void ip_rcv_icmp(net::Packet_ptr) {
  MYINFO("ICMP got packet from IP");

  pass_count[net::Protocol::ICMPv4]++;
}

void ip_drop(net::Packet_ptr, net::IP4::Direction dir, net::IP4::Drop_reason reason) {
  last_drop_reason = reason;
  last_drop_direction = dir;
  ip_packets_dropped++;
  MYINFO("Packet dropped. Reason: %s", drop_reasons[reason].c_str());
}

#define EXPECT_DROP(PCKT, DIRECTION, REASON)            \
  {                                                     \
    auto dropcount = ip_packets_dropped;                \
    nic.receive(PCKT);                                  \
    EXPECT(ip_packets_dropped == dropcount + 1);        \
    EXPECT(last_drop_direction == net::IP4::DIRECTION); \
    EXPECT(last_drop_reason == net::IP4::REASON);       \
  }                                                     \

#define EXPECT_PASS(PCKT, PROTO)                        \
  {                                                     \
    auto passed = pass_count[PROTO];                    \
    nic.receive(PCKT);                                  \
    EXPECT(pass_count[PROTO] == passed + 1);            \
  }                                                     \

int sections = 0;

using namespace net;

CASE("IP4 is still a thing")
{

  INFO("Unit", "IP4 is still a thing");

  SETUP("A pre-wired IP4 instance with custom upstream handlers"){

    Nic_mock nic;
    Inet4 inet{nic};

    inet.ip_obj().set_drop_handler(ip_drop);
    inet.ip_obj().set_udp_handler(ip_rcv_udp);
    inet.ip_obj().set_tcp_handler(ip_rcv_tcp);
    inet.ip_obj().set_icmp_handler(ip_rcv_icmp);

    // Garbage packets

    SECTION("Raw, uninitialized packets get dropped"){
      auto raw_pckt = inet.create_packet();
      EXPECT_DROP(std::move(raw_pckt), Direction::Upstream, Drop_reason::Wrong_version);

      // All packets so far are dropped
      EXPECT(inet.ip_obj().get_packets_rx() == 1u);
      EXPECT(inet.ip_obj().get_packets_dropped() == 1u);
      MYINFO("Section %i done", ++sections);
    }

    SECTION("Inet-created IP packets are initialized correctly"){
      auto ip_pckt1 = inet.create_ip_packet(Protocol::ICMPv4);
      EXPECT(ip_pckt1->ip_version() == 4);
      EXPECT(ip_pckt1->is_ipv4());
      EXPECT(ip_pckt1->ip_ihl() == 5);
      EXPECT(ip_pckt1->ip_header_length() == 20);
      EXPECT(ip_pckt1->ip_dscp() == DSCP::CS0);
      EXPECT(ip_pckt1->ip_ecn() == ECN::NOT_ECT);
      EXPECT(ip_pckt1->ip_total_length() == 20);
      EXPECT(ip_pckt1->ip_id() == 0);
      EXPECT(ip_pckt1->ip_flags() == ip4::Flags::NONE);
      EXPECT(ip_pckt1->ip_frag_offs() == 0);
      EXPECT(ip_pckt1->ip_ttl() == 64);
      EXPECT(ip_pckt1->ip_protocol() == Protocol::ICMPv4);
      EXPECT(ip_pckt1->ip_checksum() == 0);
      EXPECT(ip_pckt1->ip_src() == IP4::ADDR_ANY);
      EXPECT(ip_pckt1->ip_dst() == IP4::ADDR_ANY);
      MYINFO("Section %i done", ++sections);
    }

    //
    // Proper IP packets with invalid header fields are dropped
    //

    SECTION("IP Packets with invalid checksum gets dropped"){

      auto ip_pckt1 = inet.create_ip_packet(Protocol::ICMPv4);
      auto ip_pckt2 = inet.create_ip_packet(Protocol(0));

      // Packets with default (0) checksum gets dropped
      EXPECT_DROP(std::move(ip_pckt1), Direction::Upstream, Drop_reason::Wrong_checksum);

      // Explicitly setting a wrong checksum for packet 1 cause drop as well
      ip_pckt2->set_ip_checksum(987);

      EXPECT_DROP(std::move(ip_pckt2), Direction::Upstream, Drop_reason::Wrong_checksum);

      MYINFO("Section %i done", ++sections);

    }

    SECTION("IP packets with bad destination address gets dropped") {

      // Martian packet gets dropped
      auto ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src({255,255,255,255});
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src(inet.broadcast_addr());
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src({224,0,0,10});
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src({225,1,2,3});
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      // Corner case source from multicast address gets dropped
      ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src({239,255,255,255});
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      MYINFO("Section %i done", ++sections);
    }

    //
    // Packet with unknown protocol gets dropped
    //

    SECTION("IP packet with invalid protocol gets dropped"){
      auto ip_pckt = inet.create_ip_packet((Protocol) 16);  // CHAOS
      ip_pckt->set_ip_src({10,0,0,45});
      ip_pckt->make_flight_ready();
      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Unknown_proto);
    }

    //
    // Valid packets are forwarded to proto handlers
    //

    SECTION("Valid UDP packets gets passed on"){
      // Default initialized source and (0) gets through
      // (Might be for DHCPD)
      auto ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->make_flight_ready();
      EXPECT_PASS(std::move(ip_pckt), Protocol::UDP);
    }

    SECTION("Valid TCP packets gets passed on"){
      auto ip_pckt = inet.create_ip_packet(Protocol::TCP);
      ip_pckt->make_flight_ready();
      EXPECT_PASS(std::move(ip_pckt), Protocol::TCP);
      MYINFO("Section %i done", ++sections);
    }
  }
}
<commit_msg>IP4 unit test: Added test for setting of IP header flags<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2017 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <map>
#include <common.cxx>
#include <nic_mock.hpp>
#include <net/inet4.hpp>

int ip_packets_dropped = 0;
int ip_packets_received = 0;

net::IP4::Drop_reason last_drop_reason;
net::IP4::Direction last_drop_direction;

std::map<net::IP4::Drop_reason, std::string> drop_reasons {
  {net::IP4::Drop_reason::Bad_source, "Bad source address"},
  {net::IP4::Drop_reason::Bad_destination, "Bad destination address"},
  {net::IP4::Drop_reason::Wrong_version, "Wrong version"},
  {net::IP4::Drop_reason::Wrong_checksum, "Wrong checksum"},
  {net::IP4::Drop_reason::Unknown_proto, "Unknown proto"},
  {net::IP4::Drop_reason::TTL0, "TTL 0"}
};

std::map<net::Protocol, int> pass_count {
  {net::Protocol::UDP, 0},
  {net::Protocol::TCP, 0},
  {net::Protocol::ICMPv4, 0}
};

#define MYINFO(X,...) INFO("Unit IP4", X, ##__VA_ARGS__)

void ip_rcv_udp(net::Packet_ptr) {
  MYINFO("UDP got packet from IP");

  pass_count[net::Protocol::UDP]++;
}

void ip_rcv_tcp(net::Packet_ptr) {
  MYINFO("TCP got packet from IP");

  pass_count[net::Protocol::TCP]++;
}

void ip_rcv_icmp(net::Packet_ptr) {
  MYINFO("ICMP got packet from IP");

  pass_count[net::Protocol::ICMPv4]++;
}

void ip_drop(net::Packet_ptr, net::IP4::Direction dir, net::IP4::Drop_reason reason) {
  last_drop_reason = reason;
  last_drop_direction = dir;
  ip_packets_dropped++;
  MYINFO("Packet dropped. Reason: %s", drop_reasons[reason].c_str());
}

#define EXPECT_DROP(PCKT, DIRECTION, REASON)            \
  {                                                     \
    auto dropcount = ip_packets_dropped;                \
    nic.receive(PCKT);                                  \
    EXPECT(ip_packets_dropped == dropcount + 1);        \
    EXPECT(last_drop_direction == net::IP4::DIRECTION); \
    EXPECT(last_drop_reason == net::IP4::REASON);       \
  }                                                     \

#define EXPECT_PASS(PCKT, PROTO)                        \
  {                                                     \
    auto passed = pass_count[PROTO];                    \
    nic.receive(PCKT);                                  \
    EXPECT(pass_count[PROTO] == passed + 1);            \
  }                                                     \

int sections = 0;

using namespace net;

CASE("IP4 is still a thing")
{

  INFO("Unit", "IP4 is still a thing");

  SETUP("A pre-wired IP4 instance with custom upstream handlers"){

    Nic_mock nic;
    Inet4 inet{nic};

    inet.ip_obj().set_drop_handler(ip_drop);
    inet.ip_obj().set_udp_handler(ip_rcv_udp);
    inet.ip_obj().set_tcp_handler(ip_rcv_tcp);
    inet.ip_obj().set_icmp_handler(ip_rcv_icmp);

    // Garbage packets

    SECTION("Raw, uninitialized packets get dropped"){
      auto raw_pckt = inet.create_packet();
      EXPECT_DROP(std::move(raw_pckt), Direction::Upstream, Drop_reason::Wrong_version);

      // All packets so far are dropped
      EXPECT(inet.ip_obj().get_packets_rx() == 1u);
      EXPECT(inet.ip_obj().get_packets_dropped() == 1u);
      MYINFO("Section %i done", ++sections);
    }

    SECTION("Inet-created IP packets are initialized correctly"){
      auto ip_pckt1 = inet.create_ip_packet(Protocol::ICMPv4);
      EXPECT(ip_pckt1->ip_version() == 4);
      EXPECT(ip_pckt1->is_ipv4());
      EXPECT(ip_pckt1->ip_ihl() == 5);
      EXPECT(ip_pckt1->ip_header_length() == 20);
      EXPECT(ip_pckt1->ip_dscp() == DSCP::CS0);
      EXPECT(ip_pckt1->ip_ecn() == ECN::NOT_ECT);
      EXPECT(ip_pckt1->ip_total_length() == 20);
      EXPECT(ip_pckt1->ip_id() == 0);
      EXPECT(ip_pckt1->ip_flags() == ip4::Flags::NONE);
      EXPECT(ip_pckt1->ip_frag_offs() == 0);
      EXPECT(ip_pckt1->ip_ttl() == 64);
      EXPECT(ip_pckt1->ip_protocol() == Protocol::ICMPv4);
      EXPECT(ip_pckt1->ip_checksum() == 0);
      EXPECT(ip_pckt1->ip_src() == IP4::ADDR_ANY);
      EXPECT(ip_pckt1->ip_dst() == IP4::ADDR_ANY);
      MYINFO("Section %i done", ++sections);
    }

    //
    // Proper IP packets with invalid header fields are dropped
    //

    SECTION("IP Packets with invalid checksum gets dropped"){

      auto ip_pckt1 = inet.create_ip_packet(Protocol::ICMPv4);
      auto ip_pckt2 = inet.create_ip_packet(Protocol(0));

      // Packets with default (0) checksum gets dropped
      EXPECT_DROP(std::move(ip_pckt1), Direction::Upstream, Drop_reason::Wrong_checksum);

      // Explicitly setting a wrong checksum for packet 1 cause drop as well
      ip_pckt2->set_ip_checksum(987);

      EXPECT_DROP(std::move(ip_pckt2), Direction::Upstream, Drop_reason::Wrong_checksum);

      MYINFO("Section %i done", ++sections);

    }

    SECTION("IP packets with bad destination address gets dropped") {

      // Martian packet gets dropped
      auto ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src({255,255,255,255});
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src(inet.broadcast_addr());
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src({224,0,0,10});
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src({225,1,2,3});
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      // Corner case source from multicast address gets dropped
      ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->set_ip_src({239,255,255,255});
      ip_pckt->make_flight_ready();

      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Bad_source);

      MYINFO("Section %i done", ++sections);
    }

    SECTION("IP header flags are set correctly")
    {
      auto ip_pckt = inet.create_ip_packet(Protocol::TCP);
      EXPECT(ip_pckt->ip_flags() == ip4::Flags::NONE);

      ip_pckt->set_ip_flags(ip4::Flags::DF);
      EXPECT(ip_pckt->ip_flags() == ip4::Flags::DF);

      ip_pckt->set_ip_flags(ip4::Flags::MF);
      EXPECT(ip_pckt->ip_flags() == ip4::Flags::MF);

      ip_pckt->set_ip_flags(ip4::Flags::MFDF);
      EXPECT(ip_pckt->ip_flags() == ip4::Flags::MFDF);
    }

    //
    // Packet with unknown protocol gets dropped
    //

    SECTION("IP packet with invalid protocol gets dropped"){
      auto ip_pckt = inet.create_ip_packet((Protocol) 16);  // CHAOS
      ip_pckt->set_ip_src({10,0,0,45});
      ip_pckt->make_flight_ready();
      EXPECT_DROP(std::move(ip_pckt), Direction::Upstream, Drop_reason::Unknown_proto);
    }

    //
    // Valid packets are forwarded to proto handlers
    //

    SECTION("Valid UDP packets gets passed on"){
      // Default initialized source and (0) gets through
      // (Might be for DHCPD)
      auto ip_pckt = inet.create_ip_packet(Protocol::UDP);
      ip_pckt->make_flight_ready();
      EXPECT_PASS(std::move(ip_pckt), Protocol::UDP);
    }

    SECTION("Valid TCP packets gets passed on"){
      auto ip_pckt = inet.create_ip_packet(Protocol::TCP);
      ip_pckt->make_flight_ready();
      EXPECT_PASS(std::move(ip_pckt), Protocol::TCP);
      MYINFO("Section %i done", ++sections);
    }
  }
}
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexCPP.cxx
 ** Lexer for C++, C, Java, and Javascript.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static bool IsOKBeforeRE(const int ch) {
	return (ch == '(') || (ch == '=') || (ch == ',');
}

inline bool IsAWordChar(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}

inline bool IsAWordStart(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

inline bool IsADoxygenChar(const int ch) {
	return (islower(ch) || ch == '$' || ch == '@' ||
		    ch == '\\' || ch == '&' || ch == '<' ||
			ch == '>' || ch == '#' || ch == '{' ||
			ch == '}' || ch == '[' || ch == ']');
}

inline bool IsStateComment(const int state) {
	return ((state == SCE_C_COMMENT) ||
		      (state == SCE_C_COMMENTLINE) ||
		      (state == SCE_C_COMMENTDOC) ||
		      (state == SCE_C_COMMENTDOCKEYWORD) ||
		      (state == SCE_C_COMMENTDOCKEYWORDERROR));
}

inline bool IsStateString(const int state) {
	return ((state == SCE_C_STRING) || (state == SCE_C_VERBATIM));
}

static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler) {

	WordList &keywords = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];

	bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor");

	// Do not leak onto next line
	if (initStyle == SCE_C_STRINGEOL)
		initStyle = SCE_C_DEFAULT;

	int chPrevNonWhite = ' ';
	int visibleChars = 0;
	int noDocChars = 0;
	bool lastWordWasUUID = false;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		// Handle line continuation generically.
		if (sc.ch == '\\') {
			if (sc.Match("\\\n")) {
				sc.Forward();
				sc.Forward();
				continue;
			}
			if (sc.Match("\\\r\n")) {
				sc.Forward();
				sc.Forward();
				sc.Forward();
				continue;
			}
		}

		// Determine if the current state should terminate.
		if (sc.state == SCE_C_OPERATOR) {
			sc.SetState(SCE_C_DEFAULT);
		} else if (sc.state == SCE_C_NUMBER) {
			if (!IsAWordChar(sc.ch)) {
				sc.SetState(SCE_C_DEFAULT);
			}
		} else if (sc.state == SCE_C_IDENTIFIER) {
			if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
				char s[100];
				sc.GetCurrent(s, sizeof(s));
				if (keywords.InList(s)) {
					lastWordWasUUID = strcmp(s, "uuid") == 0;
					sc.ChangeState(SCE_C_WORD);
				} else if (keywords2.InList(s)) {
					sc.ChangeState(SCE_C_WORD2);
				}
				sc.SetState(SCE_C_DEFAULT);
			}
		} else if (sc.state == SCE_C_PREPROCESSOR) {
			if (stylingWithinPreprocessor) {
				if (IsASpace(sc.ch)) {
					sc.SetState(SCE_C_DEFAULT);
				}
			} else {
				if (sc.atLineEnd) {
					sc.SetState(SCE_C_DEFAULT);
				}
			}
		} else if (sc.state == SCE_C_COMMENT) {
			if (sc.Match('*', '/')) {
				sc.Forward();
				sc.ForwardSetState(SCE_C_DEFAULT);
			}
		} else if (sc.state == SCE_C_COMMENTDOC) {
			if (sc.Match('*', '/')) {
				sc.Forward();
				sc.ForwardSetState(SCE_C_DEFAULT);
			} else if ((sc.ch == '@' || sc.ch == '\\') && (noDocChars == 0)) {
				sc.SetState(SCE_C_COMMENTDOCKEYWORD);
			} else if (sc.atLineEnd) {
				noDocChars = 0;
			} else if (!isspace(sc.ch)) {
				noDocChars++;
			}
		} else if (sc.state == SCE_C_COMMENTLINE || sc.state == SCE_C_COMMENTLINEDOC) {
			if (sc.atLineEnd) {
				sc.SetState(SCE_C_DEFAULT);
				visibleChars = 0;
			}
		} else if (sc.state == SCE_C_COMMENTDOCKEYWORD) {
			if (sc.Match('*', '/')) {
				sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
				sc.Forward();
				sc.ForwardSetState(SCE_C_DEFAULT);
			} else if (!IsADoxygenChar(sc.ch)) {
				char s[100];
				sc.GetCurrent(s, sizeof(s));
				if (!isspace(sc.ch) || !keywords3.InList(s+1)) {
					sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
				}
				sc.SetState(SCE_C_COMMENTDOC);
			}
		} else if (sc.state == SCE_C_STRING) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\"') {
				sc.ForwardSetState(SCE_C_DEFAULT);
			} else if (sc.atLineEnd) {
				sc.ChangeState(SCE_C_STRINGEOL);
				sc.ForwardSetState(SCE_C_DEFAULT);
				visibleChars = 0;
			}
		} else if (sc.state == SCE_C_CHARACTER) {
			if (sc.atLineEnd) {
				sc.ChangeState(SCE_C_STRINGEOL);
				sc.ForwardSetState(SCE_C_DEFAULT);
				visibleChars = 0;
			} else if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\'') {
				sc.ForwardSetState(SCE_C_DEFAULT);
			}
		} else if (sc.state == SCE_C_REGEX) {
			if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == '/') {
				sc.ForwardSetState(SCE_C_DEFAULT);
			} else if (sc.ch == '\\') {
				// Gobble up the quoted character
				if (sc.chNext == '\\' || sc.chNext == '/') {
					sc.Forward();
				}
			}
		} else if (sc.state == SCE_C_VERBATIM) {
			if (sc.ch == '\"') {
				if (sc.chNext == '\"') {
					sc.Forward();
				} else {
					sc.ForwardSetState(SCE_C_DEFAULT);
				}
			}
		} else if (sc.state == SCE_C_UUID) {
			if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
				sc.SetState(SCE_C_DEFAULT);
			}
		}

		// Determine if a new state should be entered.
		if (sc.state == SCE_C_DEFAULT) {
			if (sc.Match('@', '\"')) {
				sc.SetState(SCE_C_VERBATIM);
				sc.Forward();
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				if (lastWordWasUUID) {
					sc.SetState(SCE_C_UUID);
					lastWordWasUUID = false;
				} else {
					sc.SetState(SCE_C_NUMBER);
				}
			} else if (IsAWordStart(sc.ch) || (sc.ch == '@')) {
				if (lastWordWasUUID) {
					sc.SetState(SCE_C_UUID);
					lastWordWasUUID = false;
				} else {
					sc.SetState(SCE_C_IDENTIFIER);
				}
			} else if (sc.Match('/', '*')) {
				if (sc.Match("/**") || sc.Match("/*!")) {	// Support of Qt/Doxygen doc. style
					noDocChars = -1;
					sc.SetState(SCE_C_COMMENTDOC);
				} else {
					sc.SetState(SCE_C_COMMENT);
				}
				sc.Forward();	// Eat the * so it isn't used for the end of the comment
			} else if (sc.Match('/', '/')) {
				if (sc.Match("///") || sc.Match("//!"))	// Support of Qt/Doxygen doc. style
					sc.SetState(SCE_C_COMMENTLINEDOC);
				else
					sc.SetState(SCE_C_COMMENTLINE);
			} else if (sc.ch == '/' && IsOKBeforeRE(chPrevNonWhite)) {
				sc.SetState(SCE_C_REGEX);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_C_STRING);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_C_CHARACTER);
			} else if (sc.ch == '#' && visibleChars == 0) {
				// Preprocessor commands are alone on their line
				sc.SetState(SCE_C_PREPROCESSOR);
				// Skip whitespace between # and preprocessor word
				do {
					sc.Forward();
				} while ((sc.ch == ' ') && (sc.ch == '\t') && sc.More());
				if (sc.atLineEnd) {
					sc.SetState(SCE_C_DEFAULT);
				}
			} else if (isoperator(static_cast<char>(sc.ch))) {
				sc.SetState(SCE_C_OPERATOR);
			}
		}

		if (sc.atLineEnd) {
			// Reset states to begining of colourise so no surprises
			// if different sets of lines lexed.
			chPrevNonWhite = ' ';
			visibleChars = 0;
			lastWordWasUUID = false;
		}
		if (!IsASpace(sc.ch)) {
			chPrevNonWhite = sc.ch;
			visibleChars++;
		}
	}
	sc.Complete();
}

static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *[],
                            Accessor &styler) {
	bool foldComment = styler.GetPropertyInt("fold.comment");
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1);
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;
	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		if (foldComment &&
			(style == SCE_C_COMMENT || style == SCE_C_COMMENTDOC)) {
			if (style != stylePrev) {
				levelCurrent++;
			} else if ((style != styleNext) && !atEOL) {
				// Comments don't end at end of line and the next character may be unstyled.
				levelCurrent--;
			}
		}
		if (style == SCE_C_OPERATOR) {
			if (ch == '{') {
				levelCurrent++;
			} else if (ch == '}') {
				levelCurrent--;
			}
		}
		if (atEOL) {
			int lev = levelPrev;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
	}
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc, "cpp", FoldCppDoc);
LexerModule lmTCL(SCLEX_TCL, ColouriseCppDoc, "tcl", FoldCppDoc);
<commit_msg>Fix to ignore '*' before doc comment keywords.<commit_after>// Scintilla source code edit control
/** @file LexCPP.cxx
 ** Lexer for C++, C, Java, and Javascript.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static bool IsOKBeforeRE(const int ch) {
	return (ch == '(') || (ch == '=') || (ch == ',');
}

inline bool IsAWordChar(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}

inline bool IsAWordStart(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

inline bool IsADoxygenChar(const int ch) {
	return (islower(ch) || ch == '$' || ch == '@' ||
		    ch == '\\' || ch == '&' || ch == '<' ||
			ch == '>' || ch == '#' || ch == '{' ||
			ch == '}' || ch == '[' || ch == ']');
}

inline bool IsStateComment(const int state) {
	return ((state == SCE_C_COMMENT) ||
		      (state == SCE_C_COMMENTLINE) ||
		      (state == SCE_C_COMMENTDOC) ||
		      (state == SCE_C_COMMENTDOCKEYWORD) ||
		      (state == SCE_C_COMMENTDOCKEYWORDERROR));
}

inline bool IsStateString(const int state) {
	return ((state == SCE_C_STRING) || (state == SCE_C_VERBATIM));
}

static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler) {

	WordList &keywords = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];

	bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor");

	// Do not leak onto next line
	if (initStyle == SCE_C_STRINGEOL)
		initStyle = SCE_C_DEFAULT;

	int chPrevNonWhite = ' ';
	int visibleChars = 0;
	int noDocChars = 0;
	bool lastWordWasUUID = false;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		// Handle line continuation generically.
		if (sc.ch == '\\') {
			if (sc.Match("\\\n")) {
				sc.Forward();
				sc.Forward();
				continue;
			}
			if (sc.Match("\\\r\n")) {
				sc.Forward();
				sc.Forward();
				sc.Forward();
				continue;
			}
		}

		// Determine if the current state should terminate.
		if (sc.state == SCE_C_OPERATOR) {
			sc.SetState(SCE_C_DEFAULT);
		} else if (sc.state == SCE_C_NUMBER) {
			if (!IsAWordChar(sc.ch)) {
				sc.SetState(SCE_C_DEFAULT);
			}
		} else if (sc.state == SCE_C_IDENTIFIER) {
			if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
				char s[100];
				sc.GetCurrent(s, sizeof(s));
				if (keywords.InList(s)) {
					lastWordWasUUID = strcmp(s, "uuid") == 0;
					sc.ChangeState(SCE_C_WORD);
				} else if (keywords2.InList(s)) {
					sc.ChangeState(SCE_C_WORD2);
				}
				sc.SetState(SCE_C_DEFAULT);
			}
		} else if (sc.state == SCE_C_PREPROCESSOR) {
			if (stylingWithinPreprocessor) {
				if (IsASpace(sc.ch)) {
					sc.SetState(SCE_C_DEFAULT);
				}
			} else {
				if (sc.atLineEnd) {
					sc.SetState(SCE_C_DEFAULT);
				}
			}
		} else if (sc.state == SCE_C_COMMENT) {
			if (sc.Match('*', '/')) {
				sc.Forward();
				sc.ForwardSetState(SCE_C_DEFAULT);
			}
		} else if (sc.state == SCE_C_COMMENTDOC) {
			if (sc.Match('*', '/')) {
				sc.Forward();
				sc.ForwardSetState(SCE_C_DEFAULT);
			} else if ((sc.ch == '@' || sc.ch == '\\') && (noDocChars == 0)) {
				sc.SetState(SCE_C_COMMENTDOCKEYWORD);
			} else if (sc.atLineEnd) {
				noDocChars = 0;
			} else if (!isspace(sc.ch) && (sc.ch != '*')) {
				noDocChars++;
			}
		} else if (sc.state == SCE_C_COMMENTLINE || sc.state == SCE_C_COMMENTLINEDOC) {
			if (sc.atLineEnd) {
				sc.SetState(SCE_C_DEFAULT);
				visibleChars = 0;
			}
		} else if (sc.state == SCE_C_COMMENTDOCKEYWORD) {
			if (sc.Match('*', '/')) {
				sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
				sc.Forward();
				sc.ForwardSetState(SCE_C_DEFAULT);
			} else if (!IsADoxygenChar(sc.ch)) {
				char s[100];
				sc.GetCurrent(s, sizeof(s));
				if (!isspace(sc.ch) || !keywords3.InList(s+1)) {
					sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
				}
				sc.SetState(SCE_C_COMMENTDOC);
			}
		} else if (sc.state == SCE_C_STRING) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\"') {
				sc.ForwardSetState(SCE_C_DEFAULT);
			} else if (sc.atLineEnd) {
				sc.ChangeState(SCE_C_STRINGEOL);
				sc.ForwardSetState(SCE_C_DEFAULT);
				visibleChars = 0;
			}
		} else if (sc.state == SCE_C_CHARACTER) {
			if (sc.atLineEnd) {
				sc.ChangeState(SCE_C_STRINGEOL);
				sc.ForwardSetState(SCE_C_DEFAULT);
				visibleChars = 0;
			} else if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\'') {
				sc.ForwardSetState(SCE_C_DEFAULT);
			}
		} else if (sc.state == SCE_C_REGEX) {
			if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == '/') {
				sc.ForwardSetState(SCE_C_DEFAULT);
			} else if (sc.ch == '\\') {
				// Gobble up the quoted character
				if (sc.chNext == '\\' || sc.chNext == '/') {
					sc.Forward();
				}
			}
		} else if (sc.state == SCE_C_VERBATIM) {
			if (sc.ch == '\"') {
				if (sc.chNext == '\"') {
					sc.Forward();
				} else {
					sc.ForwardSetState(SCE_C_DEFAULT);
				}
			}
		} else if (sc.state == SCE_C_UUID) {
			if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
				sc.SetState(SCE_C_DEFAULT);
			}
		}

		// Determine if a new state should be entered.
		if (sc.state == SCE_C_DEFAULT) {
			if (sc.Match('@', '\"')) {
				sc.SetState(SCE_C_VERBATIM);
				sc.Forward();
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				if (lastWordWasUUID) {
					sc.SetState(SCE_C_UUID);
					lastWordWasUUID = false;
				} else {
					sc.SetState(SCE_C_NUMBER);
				}
			} else if (IsAWordStart(sc.ch) || (sc.ch == '@')) {
				if (lastWordWasUUID) {
					sc.SetState(SCE_C_UUID);
					lastWordWasUUID = false;
				} else {
					sc.SetState(SCE_C_IDENTIFIER);
				}
			} else if (sc.Match('/', '*')) {
				if (sc.Match("/**") || sc.Match("/*!")) {	// Support of Qt/Doxygen doc. style
					noDocChars = 0;
					sc.SetState(SCE_C_COMMENTDOC);
				} else {
					sc.SetState(SCE_C_COMMENT);
				}
				sc.Forward();	// Eat the * so it isn't used for the end of the comment
			} else if (sc.Match('/', '/')) {
				if (sc.Match("///") || sc.Match("//!"))	// Support of Qt/Doxygen doc. style
					sc.SetState(SCE_C_COMMENTLINEDOC);
				else
					sc.SetState(SCE_C_COMMENTLINE);
			} else if (sc.ch == '/' && IsOKBeforeRE(chPrevNonWhite)) {
				sc.SetState(SCE_C_REGEX);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_C_STRING);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_C_CHARACTER);
			} else if (sc.ch == '#' && visibleChars == 0) {
				// Preprocessor commands are alone on their line
				sc.SetState(SCE_C_PREPROCESSOR);
				// Skip whitespace between # and preprocessor word
				do {
					sc.Forward();
				} while ((sc.ch == ' ') && (sc.ch == '\t') && sc.More());
				if (sc.atLineEnd) {
					sc.SetState(SCE_C_DEFAULT);
				}
			} else if (isoperator(static_cast<char>(sc.ch))) {
				sc.SetState(SCE_C_OPERATOR);
			}
		}

		if (sc.atLineEnd) {
			// Reset states to begining of colourise so no surprises
			// if different sets of lines lexed.
			chPrevNonWhite = ' ';
			visibleChars = 0;
			lastWordWasUUID = false;
		}
		if (!IsASpace(sc.ch)) {
			chPrevNonWhite = sc.ch;
			visibleChars++;
		}
	}
	sc.Complete();
}

static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *[],
                            Accessor &styler) {
	bool foldComment = styler.GetPropertyInt("fold.comment");
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1);
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;
	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		if (foldComment &&
			(style == SCE_C_COMMENT || style == SCE_C_COMMENTDOC)) {
			if (style != stylePrev) {
				levelCurrent++;
			} else if ((style != styleNext) && !atEOL) {
				// Comments don't end at end of line and the next character may be unstyled.
				levelCurrent--;
			}
		}
		if (style == SCE_C_OPERATOR) {
			if (ch == '{') {
				levelCurrent++;
			} else if (ch == '}') {
				levelCurrent--;
			}
		}
		if (atEOL) {
			int lev = levelPrev;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
	}
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc, "cpp", FoldCppDoc);
LexerModule lmTCL(SCLEX_TCL, ColouriseCppDoc, "tcl", FoldCppDoc);
<|endoftext|>


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

  Program:   Visualization Library
  Module:    LineSrc.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
//
// Methods for Line generator
//
#include <math.h>
#include "LineSrc.hh"
#include "FPoints.hh"
#include "FTCoords.hh"

vlLineSource::vlLineSource(int res)
{
  this->Pt1[0] = -0.5;
  this->Pt1[1] =  0.0;
  this->Pt1[2] =  0.0;

  this->Pt2[0] =  0.5;
  this->Pt2[1] =  0.0;
  this->Pt2[2] =  0.0;

  this->Resolution = (res < 1 ? 1 : res);
}

void vlLineSource::Execute()
{
  int numLines=this->Resolution;
  int numPts=this->Resolution+1;
  float x[3], tc[2], v[3];
  int i, j;
  int pts[2];
  vlFloatPoints *newPoints;
  vlFloatTCoords *newTCoords;
  vlCellArray *newLines;
//
// Set things up; allocate memory
//
  this->Initialize();

  newPoints = new vlFloatPoints(numPts);
  newTCoords = new vlFloatTCoords(numPts,2);

  newLines = new vlCellArray;
  newLines->Initialize(newLines->EstimateSize(numLines,2));
//
// Generate points and texture coordinates
//
  for (i=0; i<3; i++) v[i] = this->Pt2[i] - this->Pt1[i];

  tc[1] = 0.0;
  for (i=0; i<numPts; i++)
    {
    tc[0] = ((float)i/this->Resolution);
    for (j=0; j<3; j++) x[i] = this->Pt1[j] + tc[0]*v[j];
    newPoints->InsertPoint(i,x);
    newTCoords->InsertTCoord(i,tc);
    }
//
//  Generate lines
//
  for (i=0; i < numLines; i++)
    {
    pts[0] = i;
    pts[1] = i+1;
    newLines->InsertNextCell(2,pts);
    }
//
// Update ourselves
//
  this->SetPoints(newPoints);
  this->PointData.SetTCoords(newTCoords);
  this->SetLines(newLines);
}

void vlLineSource::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlLineSource::GetClassName()))
    {
    vlPolySource::PrintSelf(os,indent);

    os << indent << "Resolution: " << this->Resolution << "\n";

    os << indent << "Point 1: (" << this->Pt1[0] << ", "
                                  << this->Pt1[1] << ", "
                                  << this->Pt1[2] << ")\n";

    os << indent << "Point 2: (" << this->Pt2[0] << ", "
                                  << this->Pt2[1] << ", "
                                  << this->Pt2[2] << ")\n";
    }
}
<commit_msg>ERR: Fixed bug.<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    LineSrc.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
//
// Methods for Line generator
//
#include <math.h>
#include "LineSrc.hh"
#include "FPoints.hh"
#include "FTCoords.hh"

vlLineSource::vlLineSource(int res)
{
  this->Pt1[0] = -0.5;
  this->Pt1[1] =  0.0;
  this->Pt1[2] =  0.0;

  this->Pt2[0] =  0.5;
  this->Pt2[1] =  0.0;
  this->Pt2[2] =  0.0;

  this->Resolution = (res < 1 ? 1 : res);
}

void vlLineSource::Execute()
{
  int numLines=this->Resolution;
  int numPts=this->Resolution+1;
  float x[3], tc[2], v[3];
  int i, j;
  int pts[2];
  vlFloatPoints *newPoints;
  vlFloatTCoords *newTCoords;
  vlCellArray *newLines;
//
// Set things up; allocate memory
//
  this->Initialize();

  newPoints = new vlFloatPoints(numPts);
  newTCoords = new vlFloatTCoords(numPts,2);

  newLines = new vlCellArray;
  newLines->Initialize(newLines->EstimateSize(numLines,2));
//
// Generate points and texture coordinates
//
  for (i=0; i<3; i++) v[i] = this->Pt2[i] - this->Pt1[i];

  tc[1] = 0.0;
  for (i=0; i<numPts; i++)
    {
    tc[0] = ((float)i/this->Resolution);
    for (j=0; j<3; j++) x[j] = this->Pt1[j] + tc[0]*v[j];
    newPoints->InsertPoint(i,x);
    newTCoords->InsertTCoord(i,tc);
    }
//
//  Generate lines
//
  for (i=0; i < numLines; i++)
    {
    pts[0] = i;
    pts[1] = i+1;
    newLines->InsertNextCell(2,pts);
    }
//
// Update ourselves
//
  this->SetPoints(newPoints);
  this->PointData.SetTCoords(newTCoords);
  this->SetLines(newLines);
}

void vlLineSource::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlLineSource::GetClassName()))
    {
    vlPolySource::PrintSelf(os,indent);

    os << indent << "Resolution: " << this->Resolution << "\n";

    os << indent << "Point 1: (" << this->Pt1[0] << ", "
                                  << this->Pt1[1] << ", "
                                  << this->Pt1[2] << ")\n";

    os << indent << "Point 2: (" << this->Pt2[0] << ", "
                                  << this->Pt2[1] << ", "
                                  << this->Pt2[2] << ")\n";
    }
}
<|endoftext|>


<commit_before>#include "MadCam.h"

//--------------------------------------------------------------
void MadCam::setup(){
  ofSetVerticalSync(true);
  parseConfig();
  midiHandler.registerHost(this);
  oscHandler.registerHost(this);
  cameras.setup();
}

//--------------------------------------------------------------
void MadCam::update(){
  ofBackground(0,0,0);
  oscHandler.process();
  cameras.update();
}

void
MadCam::setScene(int idx)
{
  cout << "SET SCENE index: " << idx << " num scenes: " << config.sceneMap.size() << endl;
  if(idx < 0 || idx >= config.sceneMap.size()) return;

  cout << "SET SCENE layout: " << config.sceneMap.at(idx).layout << endl;
  cout << "SET SCENE viewMode: " << config.sceneMap.at(idx).viewMode << endl;

  cameras.setLayout(config.sceneMap.at(idx).layout);
  cameras.setViewMode(config.sceneMap.at(idx).viewMode);

  cameras.setTriggerMode(config.sceneMap.at(idx).triggerMode);
  cameras.setColorMode(config.sceneMap.at(idx).fx);
  cameras.setFxAmount(config.sceneMap.at(idx).amountX, config.sceneMap.at(idx).amountY);

  for (uint i = 0; i < config.sceneMap.at(idx).slots.size(); i++) {
    cameras.setSlot(i, config.sceneMap.at(idx).slots.at(i));
  }
}

//--------------------------------------------------------------
void MadCam::draw(){
  cameras.draw();
  // ofDrawBitmapString(ofGetFrameRate(),20,20);
}

//--------------------------------------------------------------
void
MadCam::windowResized(int w, int h)
{
  cameras.setDimensions(w, h);
}

//--------------------------------------------------------------
void MadCam::exit() {
  // clean up
  midiHandler.close();
}

//--------------------------------------------------------------
void MadCam::keyPressed(int key){
  if(key == 117)
    cameras.reloadShaders();

  if(key == 257)
    cameras.trigger(0);

  if(key == 258)
    cameras.trigger(1);

  if(key == 259)
    cameras.trigger(2);

  if(key == 260)
    cameras.trigger(3);

  // if(key >= baseKey && key < (baseKey + cameras.getNumCameras())) {
  //   cameras.setSlot((key % baseKey) % cameras.getNumCameras());
  //   return;
  // }

  switch(key) {
    case 113:
      cameras.setLayout(SINGLE);
      break;
    case 119:
      cameras.setLayout(DUAL_HORIZ);
      break;
    case 101:
      cameras.setLayout(TRIPLE_HORIZ);
      break;
    case 114:
      cameras.setLayout(TILED);
      break;
    case 116:
      cameras.setLayout(MONOCLE);
      break;
    case 99:
      cameras.setViewMode((CROP));
      break;
    case 115:
      cameras.setViewMode((SCALE));
      break;
    case 54:
      cameras.setColorMode(0);
      break;
    case 55:
      cameras.setColorMode(1);
      break;
    case 56:
      cameras.setColorMode(2);
      break;
    case 57:
      cameras.setColorMode(3);
      break;
    case 48:
      cameras.setColorMode(4);
      break;
    case 45:
      cameras.setColorMode(5);
      break;
  }
}

void
MadCam::parseConfig()
{
  if(XML.loadFile("settings.xml"))
    cout << "settings.xml loaded!" << endl;
  else
    cout << "settings.xml NOT loaded!" << endl;

  vector<tuple<int,int>> noteMap;
  vector<Scene> sceneMap;

  // MIDI SETUP
  XML.pushTag("settings",0);
  XML.pushTag("midi",0);

  uint numMappingTags = XML.getNumTags("mapping");

  if(numMappingTags > 0) {
    for(uint i = 0; i < numMappingTags; i++) {
      int note = XML.getValue("mapping:note",0,i);
      int cam  = XML.getValue("mapping:camera",0,i);
      noteMap.push_back(make_tuple(note, cam));
     }
  }

  XML.popTag();

  // SCENES
  XML.pushTag("scenes",0);

  uint numSceneTags = XML.getNumTags("scene");
  if(numSceneTags > 0) {
    for (uint i = 0; i < numSceneTags; i++) {
      Layout layout = static_cast<Layout>(XML.getValue("scene:layout", 0, i));
      ViewMode mode = static_cast<ViewMode>(XML.getValue("scene:view-mode", 0, i));
      bool trigger  = static_cast<bool>(XML.getValue("scene:trigger-mode", 0, i));
      int fx        = XML.getValue("scene:fx:type",     0, i);
      int amountX   = XML.getValue("scene:fx:amount-x", 0, i);
      int amountY   = XML.getValue("scene:fx:amount-y", 0, i);

      XML.pushTag("scene", i);

      uint numSlotTags = XML.getNumTags("slot");
      vector<int> slots;

      // cout << " num slots: " << numSlotTags << endl;

      if(numSlotTags > 0) {
        for (uint j = 0; j < numSlotTags; j++) {
          slots.push_back(XML.getValue("slot", 0, j));
          // cout << "slot at " << j << " is " << slots.at(j) << endl;
        }
      }
      XML.popTag();

      sceneMap.push_back({ layout, mode, trigger, fx, amountX, amountY, slots });
    }
  }

  config = { noteMap, sceneMap };
}

void MadCam::dragEvent(ofDragInfo dragInfo){}
void MadCam::keyReleased(int key){}
void MadCam::mouseMoved(int x, int y ){}
void MadCam::mouseDragged(int x, int y, int button){}
void MadCam::mousePressed(int x, int y, int button){}
void MadCam::mouseReleased(int x, int y, int button){}
void MadCam::gotMessage(ofMessage msg) {}

<commit_msg>cleaning up<commit_after>#include "MadCam.h"

//--------------------------------------------------------------
void MadCam::setup(){
  ofSetVerticalSync(true);
  parseConfig();
  midiHandler.registerHost(this);
  oscHandler.registerHost(this);
  cameras.setup();
}

//--------------------------------------------------------------
void MadCam::update(){
  ofBackground(0,0,0);
  oscHandler.process();
  cameras.update();
}

void
MadCam::setScene(int idx)
{
  if(idx < 0 || idx >= config.sceneMap.size()) return;

  cameras.setLayout(config.sceneMap.at(idx).layout);
  cameras.setViewMode(config.sceneMap.at(idx).viewMode);

  cameras.setTriggerMode(config.sceneMap.at(idx).triggerMode);
  cameras.setColorMode(config.sceneMap.at(idx).fx);
  cameras.setFxAmount(config.sceneMap.at(idx).amountX, config.sceneMap.at(idx).amountY);

  for (uint i = 0; i < config.sceneMap.at(idx).slots.size(); i++) {
    cameras.setSlot(i, config.sceneMap.at(idx).slots.at(i));
  }
}

//--------------------------------------------------------------
void MadCam::draw(){
  cameras.draw();
}

//--------------------------------------------------------------
void
MadCam::windowResized(int w, int h)
{
  cameras.setDimensions(w, h);
}

//--------------------------------------------------------------
void MadCam::exit() {
  midiHandler.close();
}

//--------------------------------------------------------------
void MadCam::keyPressed(int key){
  if(key == 117)
    cameras.reloadShaders();

  if(key == 257)
    cameras.trigger(0);

  if(key == 258)
    cameras.trigger(1);

  if(key == 259)
    cameras.trigger(2);

  if(key == 260)
    cameras.trigger(3);

  // if(key >= baseKey && key < (baseKey + cameras.getNumCameras())) {
  //   cameras.setSlot((key % baseKey) % cameras.getNumCameras());
  //   return;
  // }

  switch(key) {
    case 113:
      cameras.setLayout(SINGLE);
      break;
    case 119:
      cameras.setLayout(DUAL_HORIZ);
      break;
    case 101:
      cameras.setLayout(TRIPLE_HORIZ);
      break;
    case 114:
      cameras.setLayout(TILED);
      break;
    case 116:
      cameras.setLayout(MONOCLE);
      break;
    case 99:
      cameras.setViewMode((CROP));
      break;
    case 115:
      cameras.setViewMode((SCALE));
      break;
    case 54:
      cameras.setColorMode(0);
      break;
    case 55:
      cameras.setColorMode(1);
      break;
    case 56:
      cameras.setColorMode(2);
      break;
    case 57:
      cameras.setColorMode(3);
      break;
    case 48:
      cameras.setColorMode(4);
      break;
    case 45:
      cameras.setColorMode(5);
      break;
  }
}

void
MadCam::parseConfig()
{
  if(XML.loadFile("settings.xml"))
    cout << "settings.xml loaded!" << endl;
  else
    cout << "settings.xml NOT loaded!" << endl;

  vector<tuple<int,int>> noteMap;
  vector<Scene> sceneMap;

  // MIDI SETUP
  XML.pushTag("settings",0);
  XML.pushTag("midi",0);

  uint numMappingTags = XML.getNumTags("mapping");

  if(numMappingTags > 0) {
    for(uint i = 0; i < numMappingTags; i++) {
      int note = XML.getValue("mapping:note",0,i);
      int cam  = XML.getValue("mapping:camera",0,i);
      noteMap.push_back(make_tuple(note, cam));
     }
  }

  XML.popTag();

  // SCENES
  XML.pushTag("scenes",0);

  uint numSceneTags = XML.getNumTags("scene");
  if(numSceneTags > 0) {
    for (uint i = 0; i < numSceneTags; i++) {
      Layout layout = static_cast<Layout>(XML.getValue("scene:layout", 0, i));
      ViewMode mode = static_cast<ViewMode>(XML.getValue("scene:view-mode", 0, i));
      bool trigger  = static_cast<bool>(XML.getValue("scene:trigger-mode", 0, i));
      int fx        = XML.getValue("scene:fx:type",     0, i);
      int amountX   = XML.getValue("scene:fx:amount-x", 0, i);
      int amountY   = XML.getValue("scene:fx:amount-y", 0, i);

      XML.pushTag("scene", i);

      uint numSlotTags = XML.getNumTags("slot");
      vector<int> slots;

      // cout << " num slots: " << numSlotTags << endl;

      if(numSlotTags > 0) {
        for (uint j = 0; j < numSlotTags; j++) {
          slots.push_back(XML.getValue("slot", 0, j));
          // cout << "slot at " << j << " is " << slots.at(j) << endl;
        }
      }
      XML.popTag();

      sceneMap.push_back({ layout, mode, trigger, fx, amountX, amountY, slots });
    }
  }

  config = { noteMap, sceneMap };
}

void MadCam::dragEvent(ofDragInfo dragInfo){}
void MadCam::keyReleased(int key){}
void MadCam::mouseMoved(int x, int y ){}
void MadCam::mouseDragged(int x, int y, int button){}
void MadCam::mousePressed(int x, int y, int button){}
void MadCam::mouseReleased(int x, int y, int button){}
void MadCam::gotMessage(ofMessage msg) {}

<|endoftext|>