<commit_before>#include "parser.hpp"

//////////////
// Includes //
#include <istream>
#include <string>
#include <vector>
#include <tuple>

#include "json.hpp"

//////////
// Code //

// Creating a parse exception.
ParseException::ParseException(std::string type) {
    this->type = type;
}

// Returning a string to refer to this exception.
const char* ParseException::what() const throw() {
    return ("Failed to parse a " + this->type + " piece of JSON.").c_str();
}

// Checking if a given string is whitespace.
bool isWhitespace(char c) {
    switch (c) {
    case ' ':
    case '\t':
    case '\r':
    case '\n':
        return true;
    default:
        break;
    }

    return false;
}

// Returns the strings before and after a delimiter character.
std::tuple<std::string, std::string> untilChar(const std::string& str, char delim) {
    int n;
    for (n = 0; n < str.size(); n++)
        if (str[n] == delim)
            break;

    if (n + 1 >= str.size())
        return std::make_tuple(str, "");
    return std::make_tuple(str.substr(0, n), str.substr(n + 1, str.size() - 1));
}

// Checking if a character is a quote.
bool isQuote(char c) {
    return c == '"' || c == '\'';
}

// Stripping the whitespace out of a string. Unless it's within a pair of quote
// characters. Then it doesn't. :)
std::string stripWhitespace(const std::string& str) {
    std::string ret;

    bool mode = true;
    char quoteChar = '\0';

    for (auto it = str.begin(); it != str.end(); it++) {
        if (isQuote(*it) && (quoteChar == '\0' || *it == quoteChar)) {
            mode = !mode;
            quoteChar = *it;
        }

        if (!mode)
            ret.push_back(*it);
        else if (mode && !isWhitespace(*it))
            ret.push_back(*it);
    }

    return ret;
}

// Trying to specifically parse out a JSON object.
JValue parseJSONObject(const std::string& str) {
    return JValue();
}

// Trying to specifically parse out a JSON array.
JValue parseJSONArray(const std::string& str) {
    if (str[0] == '[' && str[str.size() - 1] == ']') {
        std::string useStr = str.substr(1, str.size() - 2);
        if (useStr.compare("") == 0)
            return JValue();

        std::vector<JValue> jValues;
        std::tuple<std::string, std::string> tup;
        for (tup = untilChar(useStr, ','); std::get<0>(tup).compare("") != 0; tup = untilChar(std::get<1>(tup), ','))
            jValues.push_back(parseJSON(stripWhitespace(std::get<0>(tup))));

        return JValue(jValues);
    }

    throw ParseException("parseJSONArray");
}

// Trying to specifically parse out a JSON number.
JValue parseJSONNumber(const std::string& str) {
    try {
        return JValue(stod(str));
    } catch (const std::invalid_argument& ia) {
        throw ParseException("parseJSONNumber");
    }
}

// Trying to specifically parse out a JSON string.
JValue parseJSONString(const std::string& str) {
    if (isQuote(*str.begin()) && isQuote(*(str.end() - 1))) {
        char fq = *str.begin();
        bool ok = false;
        std::string accum;

        for (auto it = str.begin() + 1; it != str.end() - 1; it++) {
            if (!ok && *it == fq)
                return JValue();
            else if ((*it) == '\\')
                ok = true;
            else
                ok = false;

            accum.push_back(*it);
        }

        return JValue(accum);
    }

    throw ParseException("parseJSONString");
}

// Trying to specifically parse out a JSON boolean.
JValue parseJSONBool(const std::string& str) {
    if (str.compare("true") == 0)
        return JValue(true);
    else if (str.compare("false") == 0)
        return JValue(false);
    throw ParseException("parseJSONBool");
}

// Trying to specifically parse out the null JSON value.
JValue parseJSONNull(const std::string& str) {
    if (str.compare("null") == 0)
        return JValue();
    throw ParseException("parseJSONNull");
}

// Parsing out a block of JSON from a string.
JValue parseJSON(const std::string& str) throw (ParseException) {
    std::vector<JValue (*)(const std::string&)> fns;
    fns.push_back(&parseJSONObject);
    fns.push_back(&parseJSONArray);
    fns.push_back(&parseJSONNumber);
    fns.push_back(&parseJSONString);
    fns.push_back(&parseJSONBool);
    fns.push_back(&parseJSONNull);

    JValue val;
    for (auto it = fns.begin(); it != fns.end(); it++) {
        val = (*it)(str);
        if (!val.isNull())
            return val;
    }

    throw ParseException("parseJSON");
}

// Parsing out a block of JSON from an istream.
JValue parseJSON(std::istream& stream) throw(ParseException) {
    std::string line, all;

    while (!stream.eof()) {
        std::getline(stream, line);
        all += line;
    }

    return parseJSON(all);
}
<commit_msg>Stopped it from failing all of everything.<commit_after>#include "parser.hpp"

//////////////
// Includes //
#include <istream>
#include <string>
#include <vector>
#include <tuple>

#include "json.hpp"

//////////
// Code //

// Creating a parse exception.
ParseException::ParseException(std::string type) {
    this->type = type;
}

// Returning a string to refer to this exception.
const char* ParseException::what() const throw() {
    return ("Failed to parse a " + this->type + " piece of JSON.").c_str();
}

// Checking if a given string is whitespace.
bool isWhitespace(char c) {
    switch (c) {
    case ' ':
    case '\t':
    case '\r':
    case '\n':
        return true;
    default:
        break;
    }

    return false;
}

// Returns the strings before and after a delimiter character.
std::tuple<std::string, std::string> untilChar(const std::string& str, char delim) {
    int n;
    for (n = 0; n < str.size(); n++)
        if (str[n] == delim)
            break;

    if (n + 1 >= str.size())
        return std::make_tuple(str, "");
    return std::make_tuple(str.substr(0, n), str.substr(n + 1, str.size() - 1));
}

// Checking if a character is a quote.
bool isQuote(char c) {
    return c == '"' || c == '\'';
}

// Stripping the whitespace out of a string. Unless it's within a pair of quote
// characters. Then it doesn't. :)
std::string stripWhitespace(const std::string& str) {
    std::string ret;

    bool mode = true;
    char quoteChar = '\0';

    for (auto it = str.begin(); it != str.end(); it++) {
        if (isQuote(*it) && (quoteChar == '\0' || *it == quoteChar)) {
            mode = !mode;
            quoteChar = *it;
        }

        if (!mode)
            ret.push_back(*it);
        else if (mode && !isWhitespace(*it))
            ret.push_back(*it);
    }

    return ret;
}

// Trying to specifically parse out a JSON object.
JValue parseJSONObject(const std::string& str) throw(ParseException) {
    throw ParseException("JObject");
}

// Trying to specifically parse out a JSON array.
JValue parseJSONArray(const std::string& str) throw(ParseException) {
    if (str[0] == '[' && str[str.size() - 1] == ']') {
        std::string useStr = str.substr(1, str.size() - 2);
        if (useStr.compare("") == 0)
            return JValue();

        std::vector<JValue> jValues;
        std::tuple<std::string, std::string> tup;
        for (tup = untilChar(useStr, ','); std::get<0>(tup).compare("") != 0; tup = untilChar(std::get<1>(tup), ','))
            jValues.push_back(parseJSON(stripWhitespace(std::get<0>(tup))));

        return JValue(jValues);
    }

    throw ParseException("parseJSONArray");
}

// Trying to specifically parse out a JSON number.
JValue parseJSONNumber(const std::string& str) throw(ParseException) {
    try {
        return JValue(stod(str));
    } catch (const std::invalid_argument& ia) {
        throw ParseException("parseJSONNumber");
    }
}

// Trying to specifically parse out a JSON string.
JValue parseJSONString(const std::string& str) throw(ParseException) {
    if (isQuote(*str.begin()) && isQuote(*(str.end() - 1))) {
        char fq = *str.begin();
        bool ok = false;
        std::string accum;

        for (auto it = str.begin() + 1; it != str.end() - 1; it++) {
            if (!ok && *it == fq)
                return JValue();
            else if ((*it) == '\\')
                ok = true;
            else
                ok = false;

            accum.push_back(*it);
        }

        return JValue(accum);
    }

    throw ParseException("parseJSONString");
}

// Trying to specifically parse out a JSON boolean.
JValue parseJSONBool(const std::string& str) throw(ParseException) {
    if (str.compare("true") == 0)
        return JValue(true);
    else if (str.compare("false") == 0)
        return JValue(false);
    throw ParseException("parseJSONBool");
}

// Trying to specifically parse out the null JSON value.
JValue parseJSONNull(const std::string& str) throw(ParseException) {
    if (str.compare("null") == 0)
        return JValue();
    throw ParseException("parseJSONNull");
}

#include <iostream>

// Parsing out a block of JSON from a string.
JValue parseJSON(const std::string& str) throw(ParseException) {
    std::vector<JValue (*)(const std::string&)> fns;
    fns.push_back(&parseJSONObject);
    fns.push_back(&parseJSONArray);
    fns.push_back(&parseJSONNumber);
    fns.push_back(&parseJSONString);
    fns.push_back(&parseJSONBool);
    fns.push_back(&parseJSONNull);

    JValue val;
    for (auto it = fns.begin(); it != fns.end(); it++) {
        try { return (*it)(str); }
        catch (const ParseException& e) { }
    }

    throw ParseException("parseJSON");
}

// Parsing out a block of JSON from an istream.
JValue parseJSON(std::istream& stream) throw(ParseException) {
    std::string line, all;

    while (!stream.eof()) {
        std::getline(stream, line);
        all += line;
    }

    return parseJSON(all);
}
<|endoftext|>


<commit_before>/*
 * The main spawn screen
 */

#include "spawnDialog_defines.hpp"

class spawnDialog
{
    idd = spawn_dialog;
    movingEnable = false;
    enableSimulation = true;
    onLoad = "uiNamespace setVariable [""UK_SpawnDialog"", _this select 0]";

    class Controls
    {
        class spawnScreen: RscFrame
        {
            idc = spawn_screen;
            text = "Spawn Selection";

            #define screenW (0.7 * 3/4)
            #define screenH 0.5
            #define screenX CENTER(1, screenW)
            #define screenY CENTER(1, screenH)

            w = screenW;
            h = screenH;
            x = screenX;
            y = screenY;
        };
        class randomSpawnButton: RscButton
        {
            idc = random_spawn_button;
            text = "Random";

            #define randomButtonW scaleFix(0.15)
            #define bottomButtonH (0.055)
            #define bottomButtonY ((screenY + screenH) - (bottomButtonH + edgeOffsetY))
            #define randomButtonX ((screenX + screenW) - randomButtonW - edgeOffsetX)

            x = randomButtonX;
            y = bottomButtonY;
            w = randomButtonW;
            h = bottomButtonH;
        };

        class spawnLocationsList: RscListBox
        {
            idc = spawn_locations_list;

            #define locationslistW (screenW - (edgeOffsetX * 2))
            #define locationslistH ((screenH - bottomButtonH) - (edgeOffsetY * 4))
            #define locationslistY (screenY + (edgeOffsetY * 2))
            #define locationslistX (screenX + edgeOffsetX)

            x = locationslistX;
            y = locationslistY;
            w = locationslistW;
            h = locationslistH;
        };
        class spawnLocationsButton: RscButton
        {
            idc = spawn_locations_button;
            text = "Spawn";

            #define spawnButtonW scaleFix(0.15)
            #define spawnButtonX (screenX + edgeOffsetX)

            x = spawnButtonX;
            y = bottomButtonY;
            w = spawnButtonW;
            h = bottomButtonH;
        };
    };
};
<commit_msg>add abort button to spawn dialog<commit_after>/*
 * The main spawn screen
 */

#include "spawnDialog_defines.hpp"

class spawnDialog
{
    idd = spawn_dialog;
    movingEnable = false;
    enableSimulation = true;
    onLoad = "uiNamespace setVariable [""UK_SpawnDialog"", _this select 0]";

    class Controls
    {
        class spawnScreen: RscFrame
        {
            idc = spawn_screen;
            text = "Spawn Selection";

            #define screenW (0.7 * 3/4)
            #define screenH 0.5
            #define screenX CENTER(1, screenW)
            #define screenY CENTER(1, screenH)

            w = screenW;
            h = screenH;
            x = screenX;
            y = screenY;
        };

        #define bottomButtonH (0.055)
        #define bottomButtonY ((screenY + screenH) - (bottomButtonH + edgeOffsetY))

        class spawnLocationsList: RscListBox
        {
            idc = spawn_locations_list;

            #define locationslistW (screenW - (edgeOffsetX * 2))
            #define locationslistH ((screenH - bottomButtonH) - (edgeOffsetY * 4))
            #define locationslistY (screenY + (edgeOffsetY * 2))
            #define locationslistX (screenX + edgeOffsetX)

            x = locationslistX;
            y = locationslistY;
            w = locationslistW;
            h = locationslistH;
        };
        class spawnLocationsButton: RscButton
        {
            idc = spawn_locations_button;
            text = "Spawn";

            #define spawnButtonW scaleFix(0.15)
            #define spawnButtonX (screenX + edgeOffsetX)

            x = spawnButtonX;
            y = bottomButtonY;
            w = spawnButtonW;
            h = bottomButtonH;
        };
        class randomSpawnButton: RscButton
        {
            idc = random_spawn_button;
            text = "Random";

            #define randomButtonW scaleFix(0.15)
            #define randomButtonX (screenX + (edgeOffsetX * 2) + spawnButtonW)

            x = randomButtonX;
            y = bottomButtonY;
            w = randomButtonW;
            h = bottomButtonH;
        };
        class abortButton: RscButton
        {
            idc = -1;
            text = "Abort";
            onButtonClick = "endMission 'LOSER'";

            #define abortButtonW scaleFix(0.15)
            #define abortButtonX ((screenX + screenW) - abortButtonW - edgeOffsetX)

            x = abortButtonX;
            y = bottomButtonY;
            w = abortButtonW;
            h = bottomButtonH;
        };
    };
};
<|endoftext|>


<commit_before>/*
 * Copyright 2016-2017 deepstreamHub GmbH
 *
 * 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 <cstdlib>
#include <cstring>

#include <message.hpp>
#include <parser.h>
#include <parser.hpp>
#include <scope_guard.hpp>
#include <use.hpp>

#include <cassert>

bool is_header_token(enum deepstream_token token)
{
	int min_event_num = TOKEN_A_A;

	return token >= min_event_num;
}

deepstream_parser_state::deepstream_parser_state(const char* p, std::size_t sz):
	buffer_(p),
	buffer_size_(sz),
	tokenizing_header_(true),
	offset_(0)
{
	assert(buffer_);
}

int deepstream_parser_handle(
	deepstream::parser::State* p_state, deepstream_token token,
	const char* text, std::size_t textlen)
{
	assert( p_state );
	assert( token != TOKEN_MAXVAL );

	return p_state->handle_token(token, text, textlen);
}

int deepstream_parser_state::handle_token(
	deepstream_token token, const char* text, std::size_t textlen)
{
	assert( token != TOKEN_MAXVAL );

	assert( text );
	assert( textlen > 0 );

	assert( token != TOKEN_EOF || *text == '\0' );
	assert( token != TOKEN_EOF || textlen == 1 );
	assert( token != TOKEN_EOF || offset_ + textlen == buffer_size_ + 1 );
	assert( token == TOKEN_EOF || offset_ + textlen <= buffer_size_ );
	assert( token == TOKEN_EOF || !std::memcmp(buffer_+offset_, text, textlen));

	assert( messages_.size() <= offset_ );
	assert( errors_.size() <= offset_ );

	DEEPSTREAM_ON_EXIT([this, textlen] () {
		this->offset_ += textlen;
	} );

	if(token == TOKEN_UNKNOWN)
		handle_error(token, text, textlen);
	else if(token == TOKEN_EOF)
	{
		assert(offset_ == buffer_size_);

		if(!tokenizing_header_)
			handle_error(token, text, textlen);
	}
	else if(token == TOKEN_PAYLOAD)
		handle_payload(token, text, textlen);
	else if(token == TOKEN_MESSAGE_SEPARATOR)
		handle_message_separator(token, text, textlen);
	else if( is_header_token(token) )
		handle_header(token, text, textlen);
	else
	{
		assert(0);
	}

	return token;
}

void deepstream_parser_state::handle_error(
	deepstream_token token, const char*, std::size_t textlen)
{
	using deepstream::parser::Error;

	assert( token == TOKEN_EOF || token == TOKEN_UNKNOWN );
	assert( textlen > 0 || (textlen == 0 && token == EOF) );

	DEEPSTREAM_ON_EXIT( [this] () {
		this->tokenizing_header_ = true; // reset parser status on exit
	} );

	if( token == TOKEN_EOF )
	{
		assert( !tokenizing_header_ );
		assert( !messages_.empty() );

		messages_.pop_back();
		errors_.emplace_back(offset_, textlen, Error::UNEXPECTED_EOF);
	}

	if( token == TOKEN_UNKNOWN && tokenizing_header_ )
	{
		errors_.emplace_back(offset_, textlen, Error::UNEXPECTED_TOKEN);
	}

	if( token == TOKEN_UNKNOWN && !tokenizing_header_ )
	{
		assert( !messages_.empty() );

		std::size_t msg_start = messages_.back().offset();
		std::size_t msg_size = messages_.back().size();
		messages_.pop_back();

		assert( msg_start + msg_size == offset_ );

		errors_.emplace_back(
			msg_start, msg_size+textlen, Error::CORRUPT_MESSAGE);
	}
}

#define DS_ADD_MSG(...) \
		do { \
			assert( textlen==deepstream::Message::Header::size(__VA_ARGS__) ); \
			messages_.emplace_back(buffer_, offset_, __VA_ARGS__); \
		} while(false)

void deepstream_parser_state::handle_header(
	deepstream_token token, const char*, std::size_t textlen)
{
	using deepstream::Topic;
	using deepstream::Action;

	assert( is_header_token(token) );
	assert( tokenizing_header_ );

	DEEPSTREAM_ON_EXIT( [this] () {
		this->tokenizing_header_ = false;
	} );

	switch(token)
	{
		// avoid compiler warnings [-Wswitch]
		case TOKEN_EOF:
		case TOKEN_UNKNOWN:
		case TOKEN_PAYLOAD:
		case TOKEN_MESSAGE_SEPARATOR:
		case TOKEN_MAXVAL:
			assert(0);
			break;

		case TOKEN_A_A:
			DS_ADD_MSG(Topic::AUTH, Action::REQUEST, true);
			break;

		case TOKEN_A_E_IAD:
			DS_ADD_MSG(Topic::AUTH, Action::ERROR_INVALID_AUTH_DATA, true);
			break;

		case TOKEN_A_E_TMAA:
			DS_ADD_MSG(Topic::AUTH, Action::ERROR_TOO_MANY_AUTH_ATTEMPTS);
			break;

		case TOKEN_A_REQ:
			DS_ADD_MSG(Topic::AUTH, Action::REQUEST);
			break;

		case TOKEN_C_A:
			DS_ADD_MSG(Topic::CONNECTION, Action::CHALLENGE_RESPONSE, true);
			break;

		case TOKEN_C_CH:
			DS_ADD_MSG(Topic::CONNECTION, Action::CHALLENGE);
			break;

		case TOKEN_C_CHR:
			DS_ADD_MSG(Topic::CONNECTION, Action::CHALLENGE_RESPONSE);
			break;

		case TOKEN_C_RED:
			DS_ADD_MSG(Topic::CONNECTION, Action::REDIRECT);
			break;

		case TOKEN_C_REJ:
			DS_ADD_MSG(Topic::CONNECTION, Action::REJECT);

		case TOKEN_E_A_L:
			DS_ADD_MSG(Topic::EVENT, Action::LISTEN, true);
			break;

		case TOKEN_E_A_S:
			DS_ADD_MSG(Topic::EVENT, Action::SUBSCRIBE, true);
			break;

		case TOKEN_E_L:
			DS_ADD_MSG(Topic::EVENT, Action::LISTEN);
			break;

		case TOKEN_E_S:
			DS_ADD_MSG(Topic::EVENT, Action::SUBSCRIBE);
			break;

		case TOKEN_E_US:
			DS_ADD_MSG(Topic::EVENT, Action::UNSUBSCRIBE);
			break;
	}
}

void deepstream_parser_state::handle_payload(
	deepstream_token token, const char* text, std::size_t textlen)
{
	using namespace deepstream::parser;

	assert( token == TOKEN_PAYLOAD );
	assert( text );
	assert( textlen > 0 );
	assert( text[0] == ASCII_UNIT_SEPARATOR );
	assert( !messages_.empty() );

	deepstream::use(token);
	deepstream::use(text);

	auto& msg = messages_.back();
	msg.arguments_.emplace_back(offset_+1, textlen-1);
	msg.size_ += textlen;
}

void deepstream_parser_state::handle_message_separator(
	deepstream_token token, const char* text, std::size_t textlen)
{
	using namespace deepstream::parser;

	assert( token == TOKEN_MESSAGE_SEPARATOR );
	assert( text );
	assert( textlen == 1 );
	assert( text[0] == ASCII_RECORD_SEPARATOR );
	assert( !messages_.empty() );

	deepstream::use(token);
	deepstream::use(text);

	DEEPSTREAM_ON_EXIT( [this] () {
		this->tokenizing_header_ = true;
	} );

	auto& msg = messages_.back();
	msg.size_ += textlen;

	std::size_t msg_offset = msg.offset();
	std::size_t msg_size = msg.size();
	std::size_t num_args = msg.arguments_.size();
	const auto& expected_num_args = msg.num_arguments();
	std::size_t min_num_args = expected_num_args.first;
	std::size_t max_num_args = expected_num_args.second;

	if( num_args >= min_num_args && num_args <= max_num_args )
		return;

	messages_.pop_back();
	errors_.emplace_back(
		msg_offset, msg_size, Error::INVALID_NUMBER_OF_ARGUMENTS);
}
<commit_msg>Test: check parsed message headers<commit_after>/*
 * Copyright 2016-2017 deepstreamHub GmbH
 *
 * 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 <cstdlib>
#include <cstring>

#include <message.hpp>
#include <parser.h>
#include <parser.hpp>
#include <scope_guard.hpp>
#include <use.hpp>

#include <cassert>

bool is_header_token(enum deepstream_token token)
{
	int min_event_num = TOKEN_A_A;

	return token >= min_event_num;
}

deepstream_parser_state::deepstream_parser_state(const char* p, std::size_t sz):
	buffer_(p),
	buffer_size_(sz),
	tokenizing_header_(true),
	offset_(0)
{
	assert(buffer_);
}

int deepstream_parser_handle(
	deepstream::parser::State* p_state, deepstream_token token,
	const char* text, std::size_t textlen)
{
	assert( p_state );
	assert( token != TOKEN_MAXVAL );

	return p_state->handle_token(token, text, textlen);
}

int deepstream_parser_state::handle_token(
	deepstream_token token, const char* text, std::size_t textlen)
{
	assert( token != TOKEN_MAXVAL );

	assert( text );
	assert( textlen > 0 );

	assert( token != TOKEN_EOF || *text == '\0' );
	assert( token != TOKEN_EOF || textlen == 1 );
	assert( token != TOKEN_EOF || offset_ + textlen == buffer_size_ + 1 );
	assert( token == TOKEN_EOF || offset_ + textlen <= buffer_size_ );
	assert( token == TOKEN_EOF || !std::memcmp(buffer_+offset_, text, textlen));

	assert( messages_.size() <= offset_ );
	assert( errors_.size() <= offset_ );

	DEEPSTREAM_ON_EXIT([this, textlen] () {
		this->offset_ += textlen;
	} );

	if(token == TOKEN_UNKNOWN)
		handle_error(token, text, textlen);
	else if(token == TOKEN_EOF)
	{
		assert(offset_ == buffer_size_);

		if(!tokenizing_header_)
			handle_error(token, text, textlen);
	}
	else if(token == TOKEN_PAYLOAD)
		handle_payload(token, text, textlen);
	else if(token == TOKEN_MESSAGE_SEPARATOR)
		handle_message_separator(token, text, textlen);
	else if( is_header_token(token) )
		handle_header(token, text, textlen);
	else
	{
		assert(0);
	}

	return token;
}

void deepstream_parser_state::handle_error(
	deepstream_token token, const char*, std::size_t textlen)
{
	using deepstream::parser::Error;

	assert( token == TOKEN_EOF || token == TOKEN_UNKNOWN );
	assert( textlen > 0 || (textlen == 0 && token == EOF) );

	DEEPSTREAM_ON_EXIT( [this] () {
		this->tokenizing_header_ = true; // reset parser status on exit
	} );

	if( token == TOKEN_EOF )
	{
		assert( !tokenizing_header_ );
		assert( !messages_.empty() );

		messages_.pop_back();
		errors_.emplace_back(offset_, textlen, Error::UNEXPECTED_EOF);
	}

	if( token == TOKEN_UNKNOWN && tokenizing_header_ )
	{
		errors_.emplace_back(offset_, textlen, Error::UNEXPECTED_TOKEN);
	}

	if( token == TOKEN_UNKNOWN && !tokenizing_header_ )
	{
		assert( !messages_.empty() );

		std::size_t msg_start = messages_.back().offset();
		std::size_t msg_size = messages_.back().size();
		messages_.pop_back();

		assert( msg_start + msg_size == offset_ );

		errors_.emplace_back(
			msg_start, msg_size+textlen, Error::CORRUPT_MESSAGE);
	}
}

#define DS_ADD_MSG(...) \
		do { \
			messages_.emplace_back(buffer_, offset_, __VA_ARGS__); \
		} while(false)

void deepstream_parser_state::handle_header(
	deepstream_token token, const char* text, std::size_t textlen)
{
	using deepstream::Topic;
	using deepstream::Action;

	assert( is_header_token(token) );
	assert( tokenizing_header_ );

	DEEPSTREAM_ON_EXIT( [this] () {
		this->tokenizing_header_ = false;
	} );

	switch(token)
	{
		// avoid compiler warnings [-Wswitch]
		case TOKEN_EOF:
		case TOKEN_UNKNOWN:
		case TOKEN_PAYLOAD:
		case TOKEN_MESSAGE_SEPARATOR:
		case TOKEN_MAXVAL:
			assert(0);
			break;

		case TOKEN_A_A:
			DS_ADD_MSG(Topic::AUTH, Action::REQUEST, true);
			break;

		case TOKEN_A_E_IAD:
			DS_ADD_MSG(Topic::AUTH, Action::ERROR_INVALID_AUTH_DATA, true);
			break;

		case TOKEN_A_E_TMAA:
			DS_ADD_MSG(Topic::AUTH, Action::ERROR_TOO_MANY_AUTH_ATTEMPTS);
			break;

		case TOKEN_A_REQ:
			DS_ADD_MSG(Topic::AUTH, Action::REQUEST);
			break;

		case TOKEN_C_A:
			DS_ADD_MSG(Topic::CONNECTION, Action::CHALLENGE_RESPONSE, true);
			break;

		case TOKEN_C_CH:
			DS_ADD_MSG(Topic::CONNECTION, Action::CHALLENGE);
			break;

		case TOKEN_C_CHR:
			DS_ADD_MSG(Topic::CONNECTION, Action::CHALLENGE_RESPONSE);
			break;

		case TOKEN_C_RED:
			DS_ADD_MSG(Topic::CONNECTION, Action::REDIRECT);
			break;

		case TOKEN_C_REJ:
			DS_ADD_MSG(Topic::CONNECTION, Action::REJECT);

		case TOKEN_E_A_L:
			DS_ADD_MSG(Topic::EVENT, Action::LISTEN, true);
			break;

		case TOKEN_E_A_S:
			DS_ADD_MSG(Topic::EVENT, Action::SUBSCRIBE, true);
			break;

		case TOKEN_E_L:
			DS_ADD_MSG(Topic::EVENT, Action::LISTEN);
			break;

		case TOKEN_E_S:
			DS_ADD_MSG(Topic::EVENT, Action::SUBSCRIBE);
			break;

		case TOKEN_E_US:
			DS_ADD_MSG(Topic::EVENT, Action::UNSUBSCRIBE);
			break;
	}

#ifndef NDEBUG
	const auto& msg = messages_.back();
	const char* p = msg.header().to_string();
	std::vector<char> bin = deepstream::Message::Header::from_human_readable(p);

	assert( textlen == msg.header().size() );
	assert( textlen == bin.size() );
	assert( std::equal(bin.cbegin(), bin.cend(), text) );
#endif
}

void deepstream_parser_state::handle_payload(
	deepstream_token token, const char* text, std::size_t textlen)
{
	using namespace deepstream::parser;

	assert( token == TOKEN_PAYLOAD );
	assert( text );
	assert( textlen > 0 );
	assert( text[0] == ASCII_UNIT_SEPARATOR );
	assert( !messages_.empty() );

	deepstream::use(token);
	deepstream::use(text);

	auto& msg = messages_.back();
	msg.arguments_.emplace_back(offset_+1, textlen-1);
	msg.size_ += textlen;
}

void deepstream_parser_state::handle_message_separator(
	deepstream_token token, const char* text, std::size_t textlen)
{
	using namespace deepstream::parser;

	assert( token == TOKEN_MESSAGE_SEPARATOR );
	assert( text );
	assert( textlen == 1 );
	assert( text[0] == ASCII_RECORD_SEPARATOR );
	assert( !messages_.empty() );

	deepstream::use(token);
	deepstream::use(text);

	DEEPSTREAM_ON_EXIT( [this] () {
		this->tokenizing_header_ = true;
	} );

	auto& msg = messages_.back();
	msg.size_ += textlen;

	std::size_t msg_offset = msg.offset();
	std::size_t msg_size = msg.size();
	std::size_t num_args = msg.arguments_.size();
	const auto& expected_num_args = msg.num_arguments();
	std::size_t min_num_args = expected_num_args.first;
	std::size_t max_num_args = expected_num_args.second;

	if( num_args >= min_num_args && num_args <= max_num_args )
		return;

	messages_.pop_back();
	errors_.emplace_back(
		msg_offset, msg_size, Error::INVALID_NUMBER_OF_ARGUMENTS);
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "native_client/src/include/portability.h"

#if NACL_OSX
#include <crt_externs.h>
#endif

#ifdef _WIN64  /* TODO(gregoryd): remove this when win64 issues are fixed */
#define NACL_NO_INLINE
#endif

EXTERN_C_BEGIN
#include "native_client/src/shared/platform/nacl_sync.h"
#include "native_client/src/shared/platform/nacl_sync_checked.h"
#include "native_client/src/trusted/service_runtime/nacl_globals.h"
#include "native_client/src/trusted/service_runtime/expiration.h"
#include "native_client/src/trusted/service_runtime/nacl_app.h"
#include "native_client/src/trusted/service_runtime/nacl_all_modules.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
#include "native_client/src/trusted/platform_qualify/nacl_os_qualify.h"
EXTERN_C_END

int verbosity = 0;

#ifdef __GNUC__

/*
 * GDB's canonical overlay managment routine.
 * We need its symbol in the symbol table so don't inline it.
 * Note: _ovly_debug_event has to be an unmangled 'C' style symbol.
 * TODO(dje): add some explanation for the non-GDB person.
 */
EXTERN_C_BEGIN
static void __attribute__ ((noinline)) _ovly_debug_event (void) {
  /*
   * The asm volatile is here as instructed by the GCC docs.
   * It's not enough to declare a function noinline.
   * GCC will still look inside the function to see if it's worth calling.
   */
  asm volatile ("");
}
EXTERN_C_END

#endif

static void StopForDebuggerInit(const struct NaClApp *state) {
  /* Put xlate_base in a place where gdb can find it.  */
  nacl_global_xlate_base = state->mem_start;

#ifdef __GNUC__
  _ovly_debug_event();
#endif
}

int SelMain(const int desc, const NaClHandle handle) {
  char *av[1];
  int ac = 1;

  char                          **envp;
  struct NaClApp                state;
  int                           main_thread_only = 1;
  int                           export_addr_to = -2;

  struct NaClApp                *nap;

  NaClErrorCode                 errcode;

  int                           ret_code = 1;
#if NACL_OSX
  // Mac dynamic libraries cannot access the environ variable directly.
  envp = *_NSGetEnviron();
#else
  extern char                   **environ;
  envp = environ;
#endif

  NaClAllModulesInit();

  /* used to be -P */
  NaClSrpcFileDescriptor = desc;
  /* used to be -X */
  export_addr_to = desc;

  /* to be passed to NaClMain, eventually... */
  av[0] = const_cast<char*>("NaClMain");

  if (!NaClAppCtor(&state)) {
    fprintf(stderr, "Error while constructing app state\n");
    goto done;
  }

  state.restrict_to_main_thread = main_thread_only;

  nap = &state;
  errcode = LOAD_OK;

  /* import IMC handle - used to be "-i" */
  NaClAddImcHandle(nap, handle, desc);

  /*
   * in order to report load error to the browser plugin through the
   * secure command channel, we do not immediate jump to cleanup code
   * on error.  rather, we continue processing (assuming earlier
   * errors do not make it inappropriate) until the secure command
   * channel is set up, and then bail out.
   */

  /*
   * Ensure this operating system platform is supported.
   */
  if (!NaClOsIsSupported()) {
    errcode = LOAD_UNSUPPORTED_OS_PLATFORM;
    nap->module_load_status = errcode;
    fprintf(stderr, "Error while loading in SelMain: %s\n",
            NaClErrorString(errcode));
  }

  /* Give debuggers a well known point at which xlate_base is known.  */
  StopForDebuggerInit(&state);

  /*
   * If export_addr_to is set to a non-negative integer, we create a
   * bound socket and socket address pair and bind the former to
   * descriptor 3 and the latter to descriptor 4.  The socket address
   * is written out to the export_addr_to descriptor.
   *
   * The service runtime also accepts a connection on the bound socket
   * and spawns a secure command channel thread to service it.
   *
   * If export_addr_to is -1, we only create the bound socket and
   * socket address pair, and we do not export to an IMC socket.  This
   * use case is typically only used in testing, where we only "dump"
   * the socket address to stdout or similar channel.
   */
  if (-2 < export_addr_to) {
    NaClCreateServiceSocket(nap);
    if (0 <= export_addr_to) {
      NaClSendServiceAddressTo(nap, export_addr_to);
      /*
       * NB: spawns a thread that uses the command channel.  we do
       * this after NaClAppLoadFile so that NaClApp object is more
       * fully populated.  Hereafter any changes to nap should be done
       * while holding locks.
       */
      NaClSecureCommandChannel(nap);
    }
  }

  NaClXMutexLock(&nap->mu);
  nap->module_load_status = LOAD_OK;
  NaClXCondVarBroadcast(&nap->cv);
  NaClXMutexUnlock(&nap->mu);

  if (NULL != nap->secure_channel) {
    /*
     * wait for start_module RPC call on secure channel thread.
     */
    NaClWaitForModuleStartStatusCall(nap);
  }

  /*
   * error reporting done; can quit now if there was an error earlier.
   */
  if (LOAD_OK != errcode) {
    goto done;
  }

  /*
   * only nap->ehdrs.e_entry is usable, no symbol table is
   * available.
   */
  if (!NaClCreateMainThread(nap,
                            ac,
                            av,
                            envp)) {
    fprintf(stderr, "creating main thread failed\n");
    goto done;
  }

  ret_code = NaClWaitForMainThreadToExit(nap);

  /*
   * exit_group or equiv kills any still running threads while module
   * addr space is still valid.  otherwise we'd have to kill threads
   * before we clean up the address space.
   */
  return ret_code;

 done:
  fflush(stdout);

  NaClAllModulesFini();

  return ret_code;
}

<commit_msg>Remove unnecessary EXTERN_C_BEGIN and EXTERN_C_END BUG=46024 TEST=None<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "native_client/src/include/portability.h"

#if NACL_OSX
#include <crt_externs.h>
#endif

#ifdef _WIN64  /* TODO(gregoryd): remove this when win64 issues are fixed */
#define NACL_NO_INLINE
#endif

#include "native_client/src/shared/platform/nacl_sync.h"
#include "native_client/src/shared/platform/nacl_sync_checked.h"
#include "native_client/src/trusted/service_runtime/nacl_globals.h"
#include "native_client/src/trusted/service_runtime/expiration.h"
#include "native_client/src/trusted/service_runtime/nacl_app.h"
#include "native_client/src/trusted/service_runtime/nacl_all_modules.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
#include "native_client/src/trusted/platform_qualify/nacl_os_qualify.h"

int verbosity = 0;

#ifdef __GNUC__

/*
 * GDB's canonical overlay managment routine.
 * We need its symbol in the symbol table so don't inline it.
 * Note: _ovly_debug_event has to be an unmangled 'C' style symbol.
 * TODO(dje): add some explanation for the non-GDB person.
 */
EXTERN_C_BEGIN
static void __attribute__ ((noinline)) _ovly_debug_event (void) {
  /*
   * The asm volatile is here as instructed by the GCC docs.
   * It's not enough to declare a function noinline.
   * GCC will still look inside the function to see if it's worth calling.
   */
  asm volatile ("");
}
EXTERN_C_END

#endif

static void StopForDebuggerInit(const struct NaClApp *state) {
  /* Put xlate_base in a place where gdb can find it.  */
  nacl_global_xlate_base = state->mem_start;

#ifdef __GNUC__
  _ovly_debug_event();
#endif
}

int SelMain(const int desc, const NaClHandle handle) {
  char *av[1];
  int ac = 1;

  char                          **envp;
  struct NaClApp                state;
  int                           main_thread_only = 1;
  int                           export_addr_to = -2;

  struct NaClApp                *nap;

  NaClErrorCode                 errcode;

  int                           ret_code = 1;
#if NACL_OSX
  // Mac dynamic libraries cannot access the environ variable directly.
  envp = *_NSGetEnviron();
#else
  extern char                   **environ;
  envp = environ;
#endif

  NaClAllModulesInit();

  /* used to be -P */
  NaClSrpcFileDescriptor = desc;
  /* used to be -X */
  export_addr_to = desc;

  /* to be passed to NaClMain, eventually... */
  av[0] = const_cast<char*>("NaClMain");

  if (!NaClAppCtor(&state)) {
    fprintf(stderr, "Error while constructing app state\n");
    goto done;
  }

  state.restrict_to_main_thread = main_thread_only;

  nap = &state;
  errcode = LOAD_OK;

  /* import IMC handle - used to be "-i" */
  NaClAddImcHandle(nap, handle, desc);

  /*
   * in order to report load error to the browser plugin through the
   * secure command channel, we do not immediate jump to cleanup code
   * on error.  rather, we continue processing (assuming earlier
   * errors do not make it inappropriate) until the secure command
   * channel is set up, and then bail out.
   */

  /*
   * Ensure this operating system platform is supported.
   */
  if (!NaClOsIsSupported()) {
    errcode = LOAD_UNSUPPORTED_OS_PLATFORM;
    nap->module_load_status = errcode;
    fprintf(stderr, "Error while loading in SelMain: %s\n",
            NaClErrorString(errcode));
  }

  /* Give debuggers a well known point at which xlate_base is known.  */
  StopForDebuggerInit(&state);

  /*
   * If export_addr_to is set to a non-negative integer, we create a
   * bound socket and socket address pair and bind the former to
   * descriptor 3 and the latter to descriptor 4.  The socket address
   * is written out to the export_addr_to descriptor.
   *
   * The service runtime also accepts a connection on the bound socket
   * and spawns a secure command channel thread to service it.
   *
   * If export_addr_to is -1, we only create the bound socket and
   * socket address pair, and we do not export to an IMC socket.  This
   * use case is typically only used in testing, where we only "dump"
   * the socket address to stdout or similar channel.
   */
  if (-2 < export_addr_to) {
    NaClCreateServiceSocket(nap);
    if (0 <= export_addr_to) {
      NaClSendServiceAddressTo(nap, export_addr_to);
      /*
       * NB: spawns a thread that uses the command channel.  we do
       * this after NaClAppLoadFile so that NaClApp object is more
       * fully populated.  Hereafter any changes to nap should be done
       * while holding locks.
       */
      NaClSecureCommandChannel(nap);
    }
  }

  NaClXMutexLock(&nap->mu);
  nap->module_load_status = LOAD_OK;
  NaClXCondVarBroadcast(&nap->cv);
  NaClXMutexUnlock(&nap->mu);

  if (NULL != nap->secure_channel) {
    /*
     * wait for start_module RPC call on secure channel thread.
     */
    NaClWaitForModuleStartStatusCall(nap);
  }

  /*
   * error reporting done; can quit now if there was an error earlier.
   */
  if (LOAD_OK != errcode) {
    goto done;
  }

  /*
   * only nap->ehdrs.e_entry is usable, no symbol table is
   * available.
   */
  if (!NaClCreateMainThread(nap,
                            ac,
                            av,
                            envp)) {
    fprintf(stderr, "creating main thread failed\n");
    goto done;
  }

  ret_code = NaClWaitForMainThreadToExit(nap);

  /*
   * exit_group or equiv kills any still running threads while module
   * addr space is still valid.  otherwise we'd have to kill threads
   * before we clean up the address space.
   */
  return ret_code;

 done:
  fflush(stdout);

  NaClAllModulesFini();

  return ret_code;
}

<|endoftext|>


<commit_before><commit_msg>Revert 32626 - Remove the expiration check from Chrome code<commit_after><|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    TestLinePlot.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkChartMatrix.h"
#include "vtkRenderWindow.h"
#include "vtkChartXY.h"
#include "vtkPlot.h"
#include "vtkTable.h"
#include "vtkFloatArray.h"
#include "vtkContextView.h"
#include "vtkContextScene.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkNew.h"

//----------------------------------------------------------------------------
int TestChartMatrix( int, char * [] )
{
  // Set up a 2D scene, add an XY chart to it
  vtkNew<vtkContextView> view;
  view->GetRenderWindow()->SetSize(400, 300);
  vtkNew<vtkChartMatrix> matrix;
  view->GetScene()->AddItem(matrix.GetPointer());
  matrix->SetSize(vtkVector2i(2, 2));

  vtkChart *chart = matrix->GetChart(vtkVector2i(0, 0));

  // Create a table with some points in it...
  vtkNew<vtkTable> table;
  vtkNew<vtkFloatArray> arrX;
  arrX->SetName("X Axis");
  table->AddColumn(arrX.GetPointer());
  vtkNew<vtkFloatArray> arrC;
  arrC->SetName("Cosine");
  table->AddColumn(arrC.GetPointer());
  vtkNew<vtkFloatArray> arrS;
  arrS->SetName("Sine");
  table->AddColumn(arrS.GetPointer());
  vtkNew<vtkFloatArray> arrS2;
  arrS2->SetName("Sine2");
  table->AddColumn(arrS2.GetPointer());
  vtkNew<vtkFloatArray> tangent;
  tangent->SetName("Tangent");
  table->AddColumn(tangent.GetPointer());
  // Test charting with a few more points...
  int numPoints = 69;
  float inc = 7.5 / (numPoints-1);
  table->SetNumberOfRows(numPoints);
  for (int i = 0; i < numPoints; ++i)
    {
    table->SetValue(i, 0, i * inc);
    table->SetValue(i, 1, cos(i * inc));
    table->SetValue(i, 2, sin(i * inc));
    table->SetValue(i, 3, sin(i * inc) + 0.5);
    table->SetValue(i, 4, tan(i * inc));
    }

  // Add multiple line plots, setting the colors etc
  vtkPlot *line = chart->AddPlot(vtkChart::POINTS);
  line->SetInput(table.GetPointer(), 0, 1);
  line->SetColor(0, 255, 0, 255);

  chart = matrix->GetChart(vtkVector2i(0, 1));
  line = chart->AddPlot(vtkChart::POINTS);
  line->SetInput(table.GetPointer(), 0, 2);
  line->SetColor(255, 0, 0, 255);

  chart = matrix->GetChart(vtkVector2i(1, 0));
  line = chart->AddPlot(vtkChart::LINE);
  line->SetInput(table.GetPointer(), 0, 3);
  line->SetColor(0, 0, 255, 255);

  chart = matrix->GetChart(vtkVector2i(1, 1));
  line = chart->AddPlot(vtkChart::POINTS);
  line->SetInput(table.GetPointer(), 0, 4);

  //Finally render the scene and compare the image to a reference image
  view->GetRenderWindow()->SetMultiSamples(0);
  view->GetInteractor()->Initialize();
  view->GetInteractor()->Start();
  return EXIT_SUCCESS;
}
<commit_msg>ENH: Use less points, make tan a bar chart.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestLinePlot.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkChartMatrix.h"
#include "vtkRenderWindow.h"
#include "vtkChartXY.h"
#include "vtkPlot.h"
#include "vtkTable.h"
#include "vtkFloatArray.h"
#include "vtkContextView.h"
#include "vtkContextScene.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkNew.h"

//----------------------------------------------------------------------------
int TestChartMatrix( int, char * [] )
{
  // Set up a 2D scene, add an XY chart to it
  vtkNew<vtkContextView> view;
  view->GetRenderWindow()->SetSize(400, 300);
  vtkNew<vtkChartMatrix> matrix;
  view->GetScene()->AddItem(matrix.GetPointer());
  matrix->SetSize(vtkVector2i(2, 2));

  vtkChart *chart = matrix->GetChart(vtkVector2i(0, 0));

  // Create a table with some points in it...
  vtkNew<vtkTable> table;
  vtkNew<vtkFloatArray> arrX;
  arrX->SetName("X Axis");
  table->AddColumn(arrX.GetPointer());
  vtkNew<vtkFloatArray> arrC;
  arrC->SetName("Cosine");
  table->AddColumn(arrC.GetPointer());
  vtkNew<vtkFloatArray> arrS;
  arrS->SetName("Sine");
  table->AddColumn(arrS.GetPointer());
  vtkNew<vtkFloatArray> arrS2;
  arrS2->SetName("Sine2");
  table->AddColumn(arrS2.GetPointer());
  vtkNew<vtkFloatArray> tangent;
  tangent->SetName("Tangent");
  table->AddColumn(tangent.GetPointer());
  // Test charting with a few more points...
  int numPoints = 42;
  float inc = 7.5 / (numPoints-1);
  table->SetNumberOfRows(numPoints);
  for (int i = 0; i < numPoints; ++i)
    {
    table->SetValue(i, 0, i * inc);
    table->SetValue(i, 1, cos(i * inc));
    table->SetValue(i, 2, sin(i * inc));
    table->SetValue(i, 3, sin(i * inc) + 0.5);
    table->SetValue(i, 4, tan(i * inc));
    }

  // Add multiple line plots, setting the colors etc
  vtkPlot *line = chart->AddPlot(vtkChart::POINTS);
  line->SetInput(table.GetPointer(), 0, 1);
  line->SetColor(0, 255, 0, 255);

  chart = matrix->GetChart(vtkVector2i(0, 1));
  line = chart->AddPlot(vtkChart::POINTS);
  line->SetInput(table.GetPointer(), 0, 2);
  line->SetColor(255, 0, 0, 255);

  chart = matrix->GetChart(vtkVector2i(1, 0));
  line = chart->AddPlot(vtkChart::LINE);
  line->SetInput(table.GetPointer(), 0, 3);
  line->SetColor(0, 0, 255, 255);

  chart = matrix->GetChart(vtkVector2i(1, 1));
  line = chart->AddPlot(vtkChart::BAR);
  line->SetInput(table.GetPointer(), 0, 4);

  //Finally render the scene and compare the image to a reference image
  view->GetRenderWindow()->SetMultiSamples(0);
  view->GetInteractor()->Initialize();
  view->GetInteractor()->Start();
  return EXIT_SUCCESS;
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
Version:   $Revision: 7837 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkStandardFileLocations.h"
#include "mitkTestingMacros.h"
#include "mitkPointSetDifferenceStatisticsCalculator.h"

//#include <QtCore>

/**
 * \brief Test class for mitkPointSetDifferenceStatisticsCalculator
 */
class mitkPointSetDifferenceStatisticsCalculatorTestClass
{

public:

  static void TestInstantiation()
    {
    // let's create an object of our class
    mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator = mitk::PointSetDifferenceStatisticsCalculator::New();
    MITK_TEST_CONDITION_REQUIRED(myPointSetDifferenceStatisticsCalculator.IsNotNull(),"Testing instantiation with constructor 1.");

    mitk::PointSet::Pointer myTestPointSet1 = mitk::PointSet::New();
    mitk::PointSet::Pointer myTestPointSet2 = mitk::PointSet::New();
    mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator2 = mitk::PointSetDifferenceStatisticsCalculator::New(myTestPointSet1,myTestPointSet2);
    MITK_TEST_CONDITION_REQUIRED(myPointSetDifferenceStatisticsCalculator2.IsNotNull(),"Testing instantiation with constructor 2.");
    }

static void TestSimpleCase()
    {

    MITK_TEST_OUTPUT(<< "Starting simple test case...");

    mitk::Point3D test;
    mitk::PointSet::Pointer testPointSet1 = mitk::PointSet::New();

    mitk::FillVector3D(test,0,0,0);
    testPointSet1->InsertPoint(0,test);

    mitk::FillVector3D(test,1,1,1);
    testPointSet1->InsertPoint(1,test);

    mitk::PointSet::Pointer testPointSet2 = mitk::PointSet::New();

    mitk::FillVector3D(test,0.5,0.5,0.5);
    testPointSet2->InsertPoint(0,test);

    mitk::FillVector3D(test,2,2,2);
    testPointSet2->InsertPoint(1,test);

    double mean = (sqrt(0.75)+sqrt(3))/2;
    double variance = ((sqrt(0.75)-mean)*(sqrt(0.75)-mean)+(sqrt(3)-mean)*(sqrt(3)-mean))/2;
    double sd = sqrt(variance);
    double rms = sqrt(3.75/2);
    double min = sqrt(0.75);
    double max = sqrt(3);
    double median = (min + max)/2;

    mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator = mitk::PointSetDifferenceStatisticsCalculator::New(testPointSet1,testPointSet2);

    MITK_TEST_CONDITION_REQUIRED((myPointSetDifferenceStatisticsCalculator->GetNumberOfPoints()==testPointSet1->GetSize()),".. Testing GetNumberOfPoints");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetMean(),mean),".. Testing GetMean");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetSD(),sd),".. Testing GetSD");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetVariance(),variance),".. Testing GetVariance");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetRMS(),rms),".. Testing GetRMS");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetMin(),min),".. Testing GetMin");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetMax(),max),".. Testing GetMax");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetMedian(),median),".. Testing GetMedian");

    testPointSet2->InsertPoint(2,test);
    myPointSetDifferenceStatisticsCalculator->SetPointSets(testPointSet1,testPointSet2);
    MITK_TEST_OUTPUT(<<"Test for exception when using differently sized point sets");
    MITK_TEST_FOR_EXCEPTION(itk::ExceptionObject,myPointSetDifferenceStatisticsCalculator->GetMean());
    mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator2 = mitk::PointSetDifferenceStatisticsCalculator::New();
    MITK_TEST_OUTPUT(<<"Test for exception when using point sets with size 0");
    MITK_TEST_FOR_EXCEPTION(itk::ExceptionObject,myPointSetDifferenceStatisticsCalculator2->GetMean());
}
};

int mitkPointSetDifferenceStatisticsCalculatorTest(int argc, char* argv[])
{
  // always start with this!
  MITK_TEST_BEGIN("mitkPointSetDifferenceStatisticsCalculatorTest")

  // let's create an object of our class
  mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator = mitk::PointSetDifferenceStatisticsCalculator::New();
  MITK_TEST_CONDITION_REQUIRED(myPointSetDifferenceStatisticsCalculator.IsNotNull(),"Testing instantiation with constructor 1.");

  mitk::PointSet::Pointer myTestPointSet1 = mitk::PointSet::New();
  mitk::PointSet::Pointer myTestPointSet2 = mitk::PointSet::New();
  mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator2 = mitk::PointSetDifferenceStatisticsCalculator::New(myTestPointSet1,myTestPointSet2);
  MITK_TEST_CONDITION_REQUIRED(myPointSetDifferenceStatisticsCalculator2.IsNotNull(),"Testing instantiation with constructor 2.");

  mitkPointSetDifferenceStatisticsCalculatorTestClass::TestInstantiation();
  mitkPointSetDifferenceStatisticsCalculatorTestClass::TestSimpleCase();
  MITK_TEST_END()
}
<commit_msg>COMP: fixed ambiguous calls to sqrt()<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
Version:   $Revision: 7837 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkStandardFileLocations.h"
#include "mitkTestingMacros.h"
#include "mitkPointSetDifferenceStatisticsCalculator.h"

//#include <QtCore>

/**
 * \brief Test class for mitkPointSetDifferenceStatisticsCalculator
 */
class mitkPointSetDifferenceStatisticsCalculatorTestClass
{

public:

  static void TestInstantiation()
    {
    // let's create an object of our class
    mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator = mitk::PointSetDifferenceStatisticsCalculator::New();
    MITK_TEST_CONDITION_REQUIRED(myPointSetDifferenceStatisticsCalculator.IsNotNull(),"Testing instantiation with constructor 1.");

    mitk::PointSet::Pointer myTestPointSet1 = mitk::PointSet::New();
    mitk::PointSet::Pointer myTestPointSet2 = mitk::PointSet::New();
    mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator2 = mitk::PointSetDifferenceStatisticsCalculator::New(myTestPointSet1,myTestPointSet2);
    MITK_TEST_CONDITION_REQUIRED(myPointSetDifferenceStatisticsCalculator2.IsNotNull(),"Testing instantiation with constructor 2.");
    }

static void TestSimpleCase()
    {

    MITK_TEST_OUTPUT(<< "Starting simple test case...");

    mitk::Point3D test;
    mitk::PointSet::Pointer testPointSet1 = mitk::PointSet::New();

    mitk::FillVector3D(test,0,0,0);
    testPointSet1->InsertPoint(0,test);

    mitk::FillVector3D(test,1,1,1);
    testPointSet1->InsertPoint(1,test);

    mitk::PointSet::Pointer testPointSet2 = mitk::PointSet::New();

    mitk::FillVector3D(test,0.5,0.5,0.5);
    testPointSet2->InsertPoint(0,test);

    mitk::FillVector3D(test,2,2,2);
    testPointSet2->InsertPoint(1,test);
    double squaredDistance1 = 0.75;
    double squaredDistance2 = 3;
    double mean = (sqrt(squaredDistance1)+sqrt(squaredDistance2))/2;
    double variance = ((sqrt(squaredDistance1)-mean)*(sqrt(squaredDistance1)-mean)+(sqrt(squaredDistance2)-mean)*(sqrt(squaredDistance2)-mean))/2;
    double sd = sqrt(variance);
    double ms = 3.75/2;
    double rms = sqrt(ms);
    double min = sqrt(squaredDistance1);
    double max = sqrt(squaredDistance2);
    double median = (min + max)/2;

    mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator = mitk::PointSetDifferenceStatisticsCalculator::New(testPointSet1,testPointSet2);

    MITK_TEST_CONDITION_REQUIRED((myPointSetDifferenceStatisticsCalculator->GetNumberOfPoints()==testPointSet1->GetSize()),".. Testing GetNumberOfPoints");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetMean(),mean),".. Testing GetMean");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetSD(),sd),".. Testing GetSD");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetVariance(),variance),".. Testing GetVariance");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetRMS(),rms),".. Testing GetRMS");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetMin(),min),".. Testing GetMin");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetMax(),max),".. Testing GetMax");
    MITK_TEST_CONDITION_REQUIRED(mitk::Equal(myPointSetDifferenceStatisticsCalculator->GetMedian(),median),".. Testing GetMedian");

    testPointSet2->InsertPoint(2,test);
    myPointSetDifferenceStatisticsCalculator->SetPointSets(testPointSet1,testPointSet2);
    MITK_TEST_OUTPUT(<<"Test for exception when using differently sized point sets");
    MITK_TEST_FOR_EXCEPTION(itk::ExceptionObject,myPointSetDifferenceStatisticsCalculator->GetMean());
    mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator2 = mitk::PointSetDifferenceStatisticsCalculator::New();
    MITK_TEST_OUTPUT(<<"Test for exception when using point sets with size 0");
    MITK_TEST_FOR_EXCEPTION(itk::ExceptionObject,myPointSetDifferenceStatisticsCalculator2->GetMean());
}
};

int mitkPointSetDifferenceStatisticsCalculatorTest(int argc, char* argv[])
{
  // always start with this!
  MITK_TEST_BEGIN("mitkPointSetDifferenceStatisticsCalculatorTest")

  // let's create an object of our class
  mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator = mitk::PointSetDifferenceStatisticsCalculator::New();
  MITK_TEST_CONDITION_REQUIRED(myPointSetDifferenceStatisticsCalculator.IsNotNull(),"Testing instantiation with constructor 1.");

  mitk::PointSet::Pointer myTestPointSet1 = mitk::PointSet::New();
  mitk::PointSet::Pointer myTestPointSet2 = mitk::PointSet::New();
  mitk::PointSetDifferenceStatisticsCalculator::Pointer myPointSetDifferenceStatisticsCalculator2 = mitk::PointSetDifferenceStatisticsCalculator::New(myTestPointSet1,myTestPointSet2);
  MITK_TEST_CONDITION_REQUIRED(myPointSetDifferenceStatisticsCalculator2.IsNotNull(),"Testing instantiation with constructor 2.");

  mitkPointSetDifferenceStatisticsCalculatorTestClass::TestInstantiation();
  mitkPointSetDifferenceStatisticsCalculatorTestClass::TestSimpleCase();
  MITK_TEST_END()
}
<|endoftext|>


<commit_before>/*=============================================================================
	Copyright (c) 2012-2013 Richard Otis

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

// declaration for functions related to EZD global minimization
// Reference: Maria Emelianenko, Zi-Kui Liu, and Qiang Du.
// "A new algorithm for the automation of phase diagram calculation." Computational Materials Science 35.1 (2006): 61-74.

#ifndef INCLUDED_EZD_MINIMIZATION
#define INCLUDED_EZD_MINIMIZATION

#include "libgibbs/include/models.hpp"
#include "libgibbs/include/compositionset.hpp"
#include "libgibbs/include/constraint.hpp"
#include "libgibbs/include/conditions.hpp"
#include <boost/bimap.hpp>
#include <vector>

namespace Optimizer {
template <typename T> struct Domain {
	std::vector<std::vector<T> > lower_left_corner;
	std::vector<std::vector<T> > upper_right_corner;
};
void LocateMinima(
		CompositionSet const &phase,
		sublattice_set const &sublset,
		evalconditions const& conditions,
		const std::size_t depth = 1
		);
}

#endif
<commit_msg>Remove Domain object<commit_after>/*=============================================================================
	Copyright (c) 2012-2013 Richard Otis

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

// declaration for functions related to EZD global minimization
// Reference: Maria Emelianenko, Zi-Kui Liu, and Qiang Du.
// "A new algorithm for the automation of phase diagram calculation." Computational Materials Science 35.1 (2006): 61-74.

#ifndef INCLUDED_EZD_MINIMIZATION
#define INCLUDED_EZD_MINIMIZATION

#include "libgibbs/include/models.hpp"
#include "libgibbs/include/compositionset.hpp"
#include "libgibbs/include/constraint.hpp"
#include "libgibbs/include/conditions.hpp"
#include <boost/bimap.hpp>
#include <vector>

namespace Optimizer {

void LocateMinima(
		CompositionSet const &phase,
		sublattice_set const &sublset,
		evalconditions const& conditions,
		const std::size_t depth = 1
		);
}

#endif
<|endoftext|>


<commit_before>/*
  WiFiServerBearSSL.cpp - SSL  server for esp8266, mostly compatible
                   with Arduino WiFi shield library

  Copyright (c) 2018 Earle F. Philhower, III

  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 St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#define LWIP_INTERNAL

extern "C" {
#include "osapi.h"
#include "ets_sys.h"
}

#include <StackThunk.h>
#include "debug.h"
#include "ESP8266WiFi.h"
#include "WiFiClient.h"
#include "WiFiServer.h"
#include "lwip/opt.h"
#include "lwip/tcp.h"
#include "lwip/inet.h"
#include <include/ClientContext.h>
#include "WiFiServerSecureBearSSL.h"

namespace BearSSL {

// Only need to call the standard server constructor
WiFiServerSecure::WiFiServerSecure(IPAddress addr, uint16_t port) : WiFiServer(addr, port) {
  stack_thunk_add_ref();
}

// Only need to call the standard server constructor
WiFiServerSecure::WiFiServerSecure(uint16_t port) : WiFiServer(port) {
  stack_thunk_add_ref();
}

// Destructor only checks if we need to delete compatibilty cert/key
WiFiServerSecure::~WiFiServerSecure() {
  stack_thunk_del_ref();
  if (_deleteChainAndKey) {
    delete _chain;
    delete _sk;
  }
}

// Specify a RSA-signed certificate and key for the server.  Only copies the pointer, the
// caller needs to preserve this chain and key for the life of the object.
void WiFiServerSecure::setRSACert(const X509List *chain, const PrivateKey *sk) {
  _chain = chain;
  _sk = sk;
}

// Specify a EC-signed certificate and key for the server.  Only copies the pointer, the
// caller needs to preserve this chain and key for the life of the object.
void WiFiServerSecure::setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk) {
  _chain = chain;
  _cert_issuer_key_type = cert_issuer_key_type;
  _sk = sk;
}

// Return a client if there's an available connection waiting.  If one is returned,
// then any validation (i.e. client cert checking) will have succeeded.
WiFiClientSecure WiFiServerSecure::available(uint8_t* status) {
  (void) status; // Unused
  if (_unclaimed) {
    if (_sk && _sk->isRSA()) {
      WiFiClientSecure result(_unclaimed, _chain, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
      _unclaimed = _unclaimed->next();
      result.setNoDelay(_noDelay);
      DEBUGV("WS:av\r\n");
      return result;
    } else if (_sk && _sk->isEC()) {
      WiFiClientSecure result(_unclaimed, _chain, _cert_issuer_key_type, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
      _unclaimed = _unclaimed->next();
      result.setNoDelay(_noDelay);
      DEBUGV("WS:av\r\n");
      return result;
    } else {
      // No key was defined, so we can't actually accept and attempt accept() and SSL handshake.
      DEBUGV("WS:nokey\r\n");
    }
  }

  // Something weird, return a no-op object
  optimistic_yield(1000);
  return WiFiClientSecure();
}

void WiFiServerSecure::setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen) {
  X509List *chain = new X509List(cert, certLen);
  PrivateKey *sk = new PrivateKey(key, keyLen);
  if (!chain || !key) {
    // OOM, fail gracefully
    delete chain;
    delete sk;
    return;
  }
  _deleteChainAndKey = true;
  setRSACert(chain, sk);
}

void WiFiServerSecure::setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen) {
  setServerKeyAndCert(key, keyLen, cert, certLen);
}

};
<commit_msg>Fix BearSSL Server WDT (#5702)<commit_after>/*
  WiFiServerBearSSL.cpp - SSL  server for esp8266, mostly compatible
                   with Arduino WiFi shield library

  Copyright (c) 2018 Earle F. Philhower, III

  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 St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#define LWIP_INTERNAL

extern "C" {
#include "osapi.h"
#include "ets_sys.h"
}

#include <StackThunk.h>
#include "debug.h"
#include "ESP8266WiFi.h"
#include "WiFiClient.h"
#include "WiFiServer.h"
#include "lwip/opt.h"
#include "lwip/tcp.h"
#include "lwip/inet.h"
#include <include/ClientContext.h>
#include "WiFiServerSecureBearSSL.h"

namespace BearSSL {

// Only need to call the standard server constructor
WiFiServerSecure::WiFiServerSecure(IPAddress addr, uint16_t port) : WiFiServer(addr, port) {
  stack_thunk_add_ref();
}

// Only need to call the standard server constructor
WiFiServerSecure::WiFiServerSecure(uint16_t port) : WiFiServer(port) {
  stack_thunk_add_ref();
}

// Destructor only checks if we need to delete compatibilty cert/key
WiFiServerSecure::~WiFiServerSecure() {
  stack_thunk_del_ref();
  if (_deleteChainAndKey) {
    delete _chain;
    delete _sk;
  }
}

// Specify a RSA-signed certificate and key for the server.  Only copies the pointer, the
// caller needs to preserve this chain and key for the life of the object.
void WiFiServerSecure::setRSACert(const X509List *chain, const PrivateKey *sk) {
  _chain = chain;
  _sk = sk;
}

// Specify a EC-signed certificate and key for the server.  Only copies the pointer, the
// caller needs to preserve this chain and key for the life of the object.
void WiFiServerSecure::setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk) {
  _chain = chain;
  _cert_issuer_key_type = cert_issuer_key_type;
  _sk = sk;
}

// Return a client if there's an available connection waiting.  If one is returned,
// then any validation (i.e. client cert checking) will have succeeded.
WiFiClientSecure WiFiServerSecure::available(uint8_t* status) {
  WiFiClientSecure client;

  (void) status; // Unused
  if (_unclaimed) {
    if (_sk && _sk->isRSA()) {
      WiFiClientSecure result(_unclaimed, _chain, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
      _unclaimed = _unclaimed->next();
      result.setNoDelay(_noDelay);
      DEBUGV("WS:av\r\n");
      client = result;
    } else if (_sk && _sk->isEC()) {
      WiFiClientSecure result(_unclaimed, _chain, _cert_issuer_key_type, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
      _unclaimed = _unclaimed->next();
      result.setNoDelay(_noDelay);
      DEBUGV("WS:av\r\n");
      client = result;
    } else {
      // No key was defined, so we can't actually accept and attempt accept() and SSL handshake.
      DEBUGV("WS:nokey\r\n");
    }
  } else {
    optimistic_yield(1000);
  }
  return client;
}

void WiFiServerSecure::setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen) {
  X509List *chain = new X509List(cert, certLen);
  PrivateKey *sk = new PrivateKey(key, keyLen);
  if (!chain || !key) {
    // OOM, fail gracefully
    delete chain;
    delete sk;
    return;
  }
  _deleteChainAndKey = true;
  setRSACert(chain, sk);
}

void WiFiServerSecure::setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen) {
  setServerKeyAndCert(key, keyLen, cert, certLen);
}

};
<|endoftext|>


<commit_before>/*********************************************************************
 *
 * Condor ClassAd library
 * Copyright (C) 1990-2003, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI and Rajesh Raman.
 *
 * This source code is covered by the Condor Public License, which can
 * be found in the accompanying LICENSE file, or online at
 * www.condorproject.org.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
 * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
 * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
 * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
 * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
 * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
 * RIGHT.
 *
 *********************************************************************/

#if defined( CLASSAD_DISTRIBUTION )
#include "classad_distribution.h"
#else
#include "condor_classad.h"
#endif
#include "lexerSource.h"
#include "xmlSink.h"
#include <fstream>
#include <iostream>
#include <ctype.h>
#include <assert.h>
#include "tester.h"

using namespace std;
#ifdef WANT_NAMESPACES
using namespace classad;
#endif

typedef map<string, Variable *> VariableMap;

/*--------------------------------------------------------------------
 *
 * Private Data Types
 *
 *--------------------------------------------------------------------*/

enum Command
{
    cmd_NoCommand,
    cmd_InvalidCommand,
    cmd_Let,
    cmd_Eval,
    cmd_Print,
    cmd_Same,
    cmd_Diff,
    cmd_Help
};

class Parameters
{
public:
	bool    debug;
    bool    verbose;
    bool    interactive;
	string  input_file;

	void ParseCommandLine(int argc, char **argv);
};

typedef map<string, Variable *> VariableMap;

/*--------------------------------------------------------------------
 *
 * Private Functions
 *
 *--------------------------------------------------------------------*/

bool read_line(string &line, Parameters &parameters);
bool replace_variables(string &line, string &error, Parameters &parameters);
Command get_command(string &line, Parameters &parameters);
void get_variable_name(string &line, bool swallow_equals, string &variable_name, Parameters &parameters);
ExprTree *get_expr(string &line, Parameters &parameters);
void get_two_exprs(string &line, ExprTree *&tree1, ExprTree *&tree2, string &error, Parameters &parameters);
void print_expr(ExprTree *tree, Parameters &parameters);
bool evaluate_expr(ExprTree *tree, Value &value, Parameters &parameters);
void shorten_line(string &line, int offset);

/*********************************************************************
 *
 * Function: Parameters::ParseCommandLine
 * Purpose:  This parses the command line. Note that it will exit
 *           if there are any problems.
 *
 *********************************************************************/
void Parameters::ParseCommandLine(int argc, char **argv)
{
	// First we set up the defaults.
	debug       = false;
    verbose     = false;
    interactive = true;
	input_file = "";

	// Then we parse to see what the user wants.
	for (int arg_index = 1; arg_index < argc; arg_index++) {
		if (   !strcmp(argv[arg_index], "-d")
            || !strcmp(argv[arg_index], "-debug")) {
			debug = true;
		} else if (   !strcmp(argv[arg_index], "-v")
                   || !strcmp(argv[arg_index], "-verbose")) {
			verbose = true;
		} else {
			if (!input_file.compare("")) {
				input_file = argv[arg_index];
                interactive = false;
			}
		}
	}

	return;
}

Variable::Variable(string &name, ExprTree *tree)
{
    _name    = name;
    _tree    = tree;
    _is_tree = true;
    return;
}

Variable::Variable(string &name, Value &value)
{
    _name    = name;
    _value   = value;
    _is_tree = false;
    _tree    = NULL;
    return;
}

Variable::~Variable()
{
    if (_is_tree && _tree != NULL) {
        delete _tree;
        _tree = NULL;
    }
    return;
}

void Variable::GetStringRepresentation(string &representation)
{
    ClassAdUnParser unparser;

    if (_is_tree) {
        unparser.Unparse(representation, _tree);
    } else {
        unparser.Unparse(representation, _value);
    }
    return;
}

VariableMap  variables;

/*********************************************************************
 *
 * Function:
 * Purpose:
 *
 *********************************************************************/
int main(int argc, char **argv)
{
    string      line;
    Parameters  parameters;

    /* --- */
    Value        value;
    Variable     *var;
    string       name = "alain";

    value.SetIntegerValue(33);
    var = new Variable(name, value);

    variables[name] = var;
    /* --- */

    parameters.ParseCommandLine(argc, argv);

    while (read_line(line, parameters) == true) {
        bool      good_line;
        string    error;
        Command   command;
        string    variable_name;
        ExprTree  *tree, *tree2;
        Variable  *variable;

        good_line = replace_variables(line, error, parameters);
        if (!good_line) {
            cout << "Error: " << error << endl;
        } else {
            command = get_command(line, parameters);
            switch (command) {
            case cmd_NoCommand:
                cout << "Error: No command on line.\n";
                break;
            case cmd_InvalidCommand:
                cout << "Unknown command on line.\n";
                break;
            case cmd_Let:
                get_variable_name(line, true, variable_name, parameters);
                tree = get_expr(line, parameters);
                if (tree == NULL) {
                    cout << "Couldn't parse rvalue.\n";
                } else {
                    variable = new Variable(variable_name, tree);
                    variables[variable_name] = variable;
                    print_expr(tree, parameters);
                }
                break;
            case cmd_Eval:
                get_variable_name(line, true, variable_name, parameters);
                tree = get_expr(line, parameters);
                if (tree == NULL) {
                    cout << "Couldn't parse rvalue.\n";
                } else {
                    Value value;
                    if (!evaluate_expr(tree, value, parameters)) {
                        cout << "Couldn't evaluate rvalue.\n";
                    } else {
                        variable = new Variable(variable_name, value);
                        variables[variable_name] = variable;
                        cout << value << endl;
                    }
                }
                break;
            case cmd_Print:
                tree = get_expr(line, parameters);
                print_expr(tree, parameters);
                break;
            case cmd_Same:
                get_two_exprs(line, tree, tree2, error, parameters);
                if (tree == NULL || tree2 == NULL) {
                    cout << "Error: " << error << endl;
                } else {
                    if (tree->SameAs(tree2)) {
                        cout << "Same.\n";
                    } else {
                        cout << "Different.\n";
                    }
                }
                break;
            case cmd_Diff:
                break;
            case cmd_Help:
                break;
            }
        }

    }
    cout << endl;
    return 0;
}

/*********************************************************************
 *
 * Function: read_line
 * Purpose:
 *
 *********************************************************************/
bool read_line(string &line, Parameters &parameters)
{
    bool have_input;

    line = "";
    have_input = true;

    if (cin.eof()) {
        have_input = false;
    } else {
        cout << "> ";
        getline(cin, line, '\n');
        if (cin.eof() && line.size() == 0) {
            have_input = false;
        } else {
            have_input = true;
        }
    }

    return have_input;
}

/*********************************************************************
 *
 * Function: replace_variables
 * Purpose:
 *
 *********************************************************************/
bool replace_variables(string &line, string &error, Parameters &parameters)
{
    bool      good_line;

    good_line = true;
    error = "";
    for (;;) {
        int      dollar, current_position;
        string   variable_name;
        string   variable_value;
        Variable *var;

        current_position = 0;
        dollar = line.find('$', current_position);
        if (dollar == -1) {
            break;
        }
        current_position = dollar + 1;
        if (!isalpha(line[current_position])){
            good_line = false;
            error = "Bad variable name.";
            break;
        }
        current_position++;
        while (isalnum(line[current_position]) || line[current_position] == '_') {
            current_position++;
        }

        variable_name = line.substr(dollar + 1, current_position - (dollar + 1));

        var = variables[variable_name];

        if (var == NULL) {
            good_line = false;
            error = "Unknown variable '$";
            error += variable_name;
            error += "'";
            break;
        }

        var->GetStringRepresentation(variable_value);

        // We have to be careful with substr() because with gcc 2.96, it likes to
        // assert/except if you give it values that are too large.
        string end;
        if (current_position < (int) line.size()) {
            end = line.substr(current_position);
        } else {
            end = "";
        }
        line = line.substr(0, dollar) + variable_value + end;
    }

    if (parameters.debug) {
        cerr << "after replacement: " << line << endl;
    }

    return good_line;
}

/*********************************************************************
 *
 * Function: get_command
 * Purpose:
 *
 *********************************************************************/
Command get_command(string &line, Parameters &parameters)
{
    int      current_position;
    int      length;
    string   command_name;
    Command  command;

    current_position = 0;
    length           = line.size();
    command_name     = "";
    command          = cmd_NoCommand;

    // Skip whitespace
    while (current_position < length && isspace(line[current_position])) {
        current_position++;
    }
    // Find command name
    while (current_position < length && isalpha(line[current_position])) {
        command_name += line[current_position];
        current_position++;
    }
    // Figure out what the command is.
    if (command_name.size() == 0) {
        command = cmd_NoCommand;
    } else if (command_name == "let") {
        command = cmd_Let;
    } else if (command_name == "eval") {
        command = cmd_Eval;
    } else if (command_name == "print") {
        command = cmd_Print;
    } else if (command_name == "same") {
        command = cmd_Same;
    } else if (command_name == "diff") {
        command = cmd_Diff;
    } else if (command_name == "help") {
        command = cmd_Help;
    } else {
        command = cmd_InvalidCommand;
    }
    shorten_line(line, current_position);
    return command;
}

/*********************************************************************
 *
 * Function: get_variable_name
 * Purpose:
 *
 *********************************************************************/
void get_variable_name(string &line, bool swallow_equals, string &variable_name, Parameters &parameters)
{
    int      current_position;
    int      length;

    current_position = 0;
    length           = line.size();
    variable_name    = "";

    // Skip whitespace
    while (current_position < length && isspace(line[current_position])) {
        current_position++;
    }
    // Find variable name
    while (current_position < length && isalpha(line[current_position])) {
        variable_name += line[current_position];
        current_position++;
    }
    if (swallow_equals) {
        // Skip whitespace
        while (current_position < length && isspace(line[current_position])) {
            current_position++;
        }
        if (line[current_position] == '=') {
            current_position++;
        }
        // We should probably report an error if we didn't find an equal sign.
        // Maybe later.
    }

    shorten_line(line, current_position);
    return;
}

/*********************************************************************
 *
 * Function: get_expr
 * Purpose:
 *
 *********************************************************************/
ExprTree *get_expr(string &line, Parameters &parameters)
{
    int               offset;
    ExprTree          *tree;
    ClassAdParser     parser;
    StringLexerSource lexer_source(&line);

    tree = parser.ParseExpression(&lexer_source, false);
    offset = lexer_source.GetCurrentLocation();
    shorten_line(line, offset);
    return tree;
}

void get_two_exprs(string &line, ExprTree *&tree1, ExprTree *&tree2, string &error, Parameters &parameters)
{
    int offset;
    ClassAdParser parser;
    StringLexerSource lexer_source(&line);

    tree1 = parser.ParseExpression(&lexer_source, false);
    if (tree1 == NULL) {
        error = "Couldn't parse first expression.";
    } else {
        if (parameters.debug) {
            cout << "Tree1: ";
            print_expr(tree1, parameters);
            cout << endl;
        }

        if (parser.PeekToken() != Lexer::LEX_COMMA) {
            error =  "Missing comma.\n";
            delete tree1;
            tree1 = NULL;
            tree2 = NULL;
        } else {
            parser.ConsumeToken();
            tree2 = parser.ParseNextExpression();
            offset = lexer_source.GetCurrentLocation();
            shorten_line(line, offset);
            if (tree2 == NULL) {
                error = "Couldn't parse second expression.";
                delete tree1;
                tree1 = NULL;
            } else if (parameters.debug){
                cout << "Tree2: ";
                print_expr(tree2, parameters);
                cout << endl;
            }
        }
    }

    return;
}

void print_expr(ExprTree *tree, Parameters &parameters)
{
    string output;
    ClassAdUnParser unparser;

    unparser.Unparse(output, tree);
    cout << output << endl;
    return;
}

bool evaluate_expr(ExprTree *tree, Value &value, Parameters &parameters)
{
    ClassAd classad;
    bool    success;

    classad.Insert("internal___", tree);
    success = classad.EvaluateAttr("internal___", value);
    classad.Remove("internal___");
    return success;
}

void shorten_line(string &line, int offset)
{
    // We have to be careful with substr() because with gcc 2.96, it likes to
    // assert/except if you give it values that are too large.
    if (offset < (int) line.size()) {
        line = line.substr(offset);
    } else {
        line = "";
    }
    return;
}
<commit_msg>Added basic help.<commit_after>/*********************************************************************
 *
 * Condor ClassAd library
 * Copyright (C) 1990-2003, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI and Rajesh Raman.
 *
 * This source code is covered by the Condor Public License, which can
 * be found in the accompanying LICENSE file, or online at
 * www.condorproject.org.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
 * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
 * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
 * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
 * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
 * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
 * RIGHT.
 *
 *********************************************************************/

#if defined(CLASSAD_DISTRIBUTION)
#include "classad_distribution.h"
#else
#include "condor_classad.h"
#endif
#include "lexerSource.h"
#include "xmlSink.h"
#include <fstream>
#include <iostream>
#include <ctype.h>
#include <assert.h>
#include "tester.h"

using namespace std;
#ifdef WANT_NAMESPACES
using namespace classad;
#endif

typedef map<string, Variable *> VariableMap;

/*--------------------------------------------------------------------
 *
 * Private Data Types
 *
 *--------------------------------------------------------------------*/

enum Command
{
    cmd_NoCommand,
    cmd_InvalidCommand,
    cmd_Let,
    cmd_Eval,
    cmd_Print,
    cmd_Same,
    cmd_Diff,
    cmd_Help
};

class Parameters
{
public:
	bool    debug;
    bool    verbose;
    bool    interactive;
	string  input_file;

	void ParseCommandLine(int argc, char **argv);
};

typedef map<string, Variable *> VariableMap;

/*--------------------------------------------------------------------
 *
 * Private Functions
 *
 *--------------------------------------------------------------------*/

bool read_line(string &line, Parameters &parameters);
bool replace_variables(string &line, string &error, Parameters &parameters);
Command get_command(string &line, Parameters &parameters);
void get_variable_name(string &line, bool swallow_equals, string &variable_name, Parameters &parameters);
ExprTree *get_expr(string &line, Parameters &parameters);
void get_two_exprs(string &line, ExprTree *&tree1, ExprTree *&tree2, string &error, Parameters &parameters);
void print_expr(ExprTree *tree, Parameters &parameters);
bool evaluate_expr(ExprTree *tree, Value &value, Parameters &parameters);
void shorten_line(string &line, int offset);
void print_help(void);
void print_version(void);

/*********************************************************************
 *
 * Function: Parameters::ParseCommandLine
 * Purpose:  This parses the command line. Note that it will exit
 *           if there are any problems.
 *
 *********************************************************************/
void Parameters::ParseCommandLine(int argc, char **argv)
{
	// First we set up the defaults.
	debug       = false;
    verbose     = false;
    interactive = true;
	input_file = "";

	// Then we parse to see what the user wants.
	for (int arg_index = 1; arg_index < argc; arg_index++) {
		if (   !strcmp(argv[arg_index], "-d")
            || !strcmp(argv[arg_index], "-debug")) {
			debug = true;
		} else if (   !strcmp(argv[arg_index], "-v")
                   || !strcmp(argv[arg_index], "-verbose")) {
			verbose = true;
		} else {
			if (!input_file.compare("")) {
				input_file = argv[arg_index];
                interactive = false;
			}
		}
	}

	return;
}

Variable::Variable(string &name, ExprTree *tree)
{
    _name    = name;
    _tree    = tree;
    _is_tree = true;
    return;
}

Variable::Variable(string &name, Value &value)
{
    _name    = name;
    _value   = value;
    _is_tree = false;
    _tree    = NULL;
    return;
}

Variable::~Variable()
{
    if (_is_tree && _tree != NULL) {
        delete _tree;
        _tree = NULL;
    }
    return;
}

void Variable::GetStringRepresentation(string &representation)
{
    ClassAdUnParser unparser;

    if (_is_tree) {
        unparser.Unparse(representation, _tree);
    } else {
        unparser.Unparse(representation, _value);
    }
    return;
}

VariableMap  variables;

/*********************************************************************
 *
 * Function:
 * Purpose:
 *
 *********************************************************************/
int main(int argc, char **argv)
{
    string      line;
    Parameters  parameters;

    print_version();

    parameters.ParseCommandLine(argc, argv);

    while (read_line(line, parameters) == true) {
        bool      good_line;
        string    error;
        Command   command;
        string    variable_name;
        ExprTree  *tree, *tree2;
        Variable  *variable;

        good_line = replace_variables(line, error, parameters);
        if (!good_line) {
            cout << "Error: " << error << endl;
        } else {
            command = get_command(line, parameters);
            switch (command) {
            case cmd_NoCommand:
                cout << "Error: No command on line.\n";
                break;
            case cmd_InvalidCommand:
                cout << "Unknown command on line.\n";
                break;
            case cmd_Let:
                get_variable_name(line, true, variable_name, parameters);
                tree = get_expr(line, parameters);
                if (tree == NULL) {
                    cout << "Couldn't parse rvalue.\n";
                } else {
                    variable = new Variable(variable_name, tree);
                    variables[variable_name] = variable;
                    print_expr(tree, parameters);
                }
                break;
            case cmd_Eval:
                get_variable_name(line, true, variable_name, parameters);
                tree = get_expr(line, parameters);
                if (tree == NULL) {
                    cout << "Couldn't parse rvalue.\n";
                } else {
                    Value value;
                    if (!evaluate_expr(tree, value, parameters)) {
                        cout << "Couldn't evaluate rvalue.\n";
                    } else {
                        variable = new Variable(variable_name, value);
                        variables[variable_name] = variable;
                        cout << value << endl;
                    }
                }
                break;
            case cmd_Print:
                tree = get_expr(line, parameters);
                print_expr(tree, parameters);
                break;
            case cmd_Same:
                get_two_exprs(line, tree, tree2, error, parameters);
                if (tree == NULL || tree2 == NULL) {
                    cout << "Error: " << error << endl;
                } else {
                    if (tree->SameAs(tree2)) {
                        cout << "Same.\n";
                    } else {
                        cout << "Different.\n";
                    }
                }
                break;
            case cmd_Diff:
                break;
            case cmd_Help:
                print_help();
                break;
            }
        }

    }
    cout << endl;
    return 0;
}

/*********************************************************************
 *
 * Function: read_line
 * Purpose:
 *
 *********************************************************************/
bool read_line(string &line, Parameters &parameters)
{
    bool have_input;

    line = "";
    have_input = true;

    if (cin.eof()) {
        have_input = false;
    } else {
        cout << "> ";
        getline(cin, line, '\n');
        if (cin.eof() && line.size() == 0) {
            have_input = false;
        } else {
            have_input = true;
        }
    }

    return have_input;
}

/*********************************************************************
 *
 * Function: replace_variables
 * Purpose:
 *
 *********************************************************************/
bool replace_variables(string &line, string &error, Parameters &parameters)
{
    bool      good_line;

    good_line = true;
    error = "";
    for (;;) {
        int      dollar, current_position;
        string   variable_name;
        string   variable_value;
        Variable *var;

        current_position = 0;
        dollar = line.find('$', current_position);
        if (dollar == -1) {
            break;
        }
        current_position = dollar + 1;
        if (!isalpha(line[current_position])){
            good_line = false;
            error = "Bad variable name.";
            break;
        }
        current_position++;
        while (isalnum(line[current_position]) || line[current_position] == '_') {
            current_position++;
        }

        variable_name = line.substr(dollar + 1, current_position - (dollar + 1));

        var = variables[variable_name];

        if (var == NULL) {
            good_line = false;
            error = "Unknown variable '$";
            error += variable_name;
            error += "'";
            break;
        }

        var->GetStringRepresentation(variable_value);

        // We have to be careful with substr() because with gcc 2.96, it likes to
        // assert/except if you give it values that are too large.
        string end;
        if (current_position < (int) line.size()) {
            end = line.substr(current_position);
        } else {
            end = "";
        }
        line = line.substr(0, dollar) + variable_value + end;
    }

    if (parameters.debug) {
        cerr << "after replacement: " << line << endl;
    }

    return good_line;
}

/*********************************************************************
 *
 * Function: get_command
 * Purpose:
 *
 *********************************************************************/
Command get_command(string &line, Parameters &parameters)
{
    int      current_position;
    int      length;
    string   command_name;
    Command  command;

    current_position = 0;
    length           = line.size();
    command_name     = "";
    command          = cmd_NoCommand;

    // Skip whitespace
    while (current_position < length && isspace(line[current_position])) {
        current_position++;
    }
    // Find command name
    while (current_position < length && isalpha(line[current_position])) {
        command_name += line[current_position];
        current_position++;
    }
    // Figure out what the command is.
    if (command_name.size() == 0) {
        command = cmd_NoCommand;
    } else if (command_name == "let") {
        command = cmd_Let;
    } else if (command_name == "eval") {
        command = cmd_Eval;
    } else if (command_name == "print") {
        command = cmd_Print;
    } else if (command_name == "same") {
        command = cmd_Same;
    } else if (command_name == "diff") {
        command = cmd_Diff;
    } else if (command_name == "help") {
        command = cmd_Help;
    } else {
        command = cmd_InvalidCommand;
    }
    shorten_line(line, current_position);
    return command;
}

/*********************************************************************
 *
 * Function: get_variable_name
 * Purpose:
 *
 *********************************************************************/
void get_variable_name(string &line, bool swallow_equals, string &variable_name, Parameters &parameters)
{
    int      current_position;
    int      length;

    current_position = 0;
    length           = line.size();
    variable_name    = "";

    // Skip whitespace
    while (current_position < length && isspace(line[current_position])) {
        current_position++;
    }
    // Find variable name
    while (current_position < length && isalpha(line[current_position])) {
        variable_name += line[current_position];
        current_position++;
    }
    if (swallow_equals) {
        // Skip whitespace
        while (current_position < length && isspace(line[current_position])) {
            current_position++;
        }
        if (line[current_position] == '=') {
            current_position++;
        }
        // We should probably report an error if we didn't find an equal sign.
        // Maybe later.
    }

    shorten_line(line, current_position);
    return;
}

/*********************************************************************
 *
 * Function: get_expr
 * Purpose:
 *
 *********************************************************************/
ExprTree *get_expr(string &line, Parameters &parameters)
{
    int               offset;
    ExprTree          *tree;
    ClassAdParser     parser;
    StringLexerSource lexer_source(&line);

    tree = parser.ParseExpression(&lexer_source, false);
    offset = lexer_source.GetCurrentLocation();
    shorten_line(line, offset);
    return tree;
}

void get_two_exprs(string &line, ExprTree *&tree1, ExprTree *&tree2, string &error, Parameters &parameters)
{
    int offset;
    ClassAdParser parser;
    StringLexerSource lexer_source(&line);

    tree1 = parser.ParseExpression(&lexer_source, false);
    if (tree1 == NULL) {
        error = "Couldn't parse first expression.";
    } else {
        if (parameters.debug) {
            cout << "Tree1: ";
            print_expr(tree1, parameters);
            cout << endl;
        }

        if (parser.PeekToken() != Lexer::LEX_COMMA) {
            error =  "Missing comma.\n";
            delete tree1;
            tree1 = NULL;
            tree2 = NULL;
        } else {
            parser.ConsumeToken();
            tree2 = parser.ParseNextExpression();
            offset = lexer_source.GetCurrentLocation();
            shorten_line(line, offset);
            if (tree2 == NULL) {
                error = "Couldn't parse second expression.";
                delete tree1;
                tree1 = NULL;
            } else if (parameters.debug){
                cout << "Tree2: ";
                print_expr(tree2, parameters);
                cout << endl;
            }
        }
    }

    return;
}

void print_expr(ExprTree *tree, Parameters &parameters)
{
    string output;
    ClassAdUnParser unparser;

    unparser.Unparse(output, tree);
    cout << output << endl;
    return;
}

bool evaluate_expr(ExprTree *tree, Value &value, Parameters &parameters)
{
    ClassAd classad;
    bool    success;

    classad.Insert("internal___", tree);
    success = classad.EvaluateAttr("internal___", value);
    classad.Remove("internal___");
    return success;
}

void shorten_line(string &line, int offset)
{
    // We have to be careful with substr() because with gcc 2.96, it likes to
    // assert/except if you give it values that are too large.
    if (offset < (int) line.size()) {
        line = line.substr(offset);
    } else {
        line = "";
    }
    return;
}

void print_help(void)
{
    print_version();

    cout << "Commands:\n";
    cout << "let name = expr   Set a variable to an unevaluated expression.\n";
    cout << "eval name = expr  Set a variable to an evaluated expression.\n";
    cout << "same expr1 expr2  Prints a message only if expr1 and expr2 are different.\n";
    cout << "diff expr1 expr2  Prints a message only if expr1 and expr2 are the same.\n";
    cout << "quit              Exit this program.\n";
    cout << "help              Print this message.\n";

}

void print_version(void)
{
    string classad_version;

    ClassAdLibraryVersion(classad_version);

    cout << "ClassAd Tester v" << classad_version << endl;

    return;
}
<|endoftext|>