<commit_before>// include library
#include <stack>
#include <string>
#include <cstring>
#include <sstream>
#include <iostream>

///*
//
// src comments: comments in sass syntax (staring with //)
// css comments: multiline comments in css syntax (starting with /*)
//
// KEEP_COMMENT: keep src comments in the resulting css code
// STRIP_COMMENT: strip out all comments (either src or css)
// CONVERT_COMMENT: convert all src comments to css comments
//
//*/

// our own header
#include "sass2scss.h"

// using std::string
using namespace std;

// add namespace for c++
namespace Sass
{

	// return the actual prettify value from options
	#define PRETTIFY(converter) (converter.options - (converter.options & 248))
	// query the options integer to check if the option is enables
	#define KEEP_COMMENT(converter) ((converter.options & SASS2SCSS_KEEP_COMMENT) == SASS2SCSS_KEEP_COMMENT)
	#define STRIP_COMMENT(converter) ((converter.options & SASS2SCSS_STRIP_COMMENT) == SASS2SCSS_STRIP_COMMENT)
	#define CONVERT_COMMENT(converter) ((converter.options & SASS2SCSS_CONVERT_COMMENT) == SASS2SCSS_CONVERT_COMMENT)

	// some makros to access the indentation stack
	#define INDENT(converter) (converter.indents.top())

	// some makros to query comment parser status
	#define IS_PARSING(converter) (converter.comment == "")
	#define IS_COMMENT(converter) (converter.comment != "")
	#define IS_SRC_COMMENT(converter) (converter.comment == "//" && ! CONVERT_COMMENT(converter))
	#define IS_CSS_COMMENT(converter) (converter.comment == "/*" || (converter.comment == "//" && CONVERT_COMMENT(converter)))

	// pretty printer helper function
	static string closer (const converter& converter)
	{
		return PRETTIFY(converter) == 0 ? " }" :
		     PRETTIFY(converter) <= 1 ? " }" :
		       "\n" + INDENT(converter) + "}";
	}

	// pretty printer helper function
	static string opener (const converter& converter)
	{
		return PRETTIFY(converter) == 0 ? " { " :
		     PRETTIFY(converter) <= 2 ? " {" :
		       "\n" + INDENT(converter) + "{";
	}

	// flush whitespace and print additional text, but
	// only print additional chars and buffer whitespace
	string flush (string& sass, converter& converter)
	{

		// return flushed
		string scss = "";

		// print whitespace buffer
		scss += PRETTIFY(converter) > 0 ?
		        converter.whitespace : "";
		// reset whitespace buffer
		converter.whitespace = "";

		// remove possible newlines from string
		size_t pos_right = sass.find_last_not_of("\n\r");
		if (pos_right == string::npos) return scss;

		// get the linefeeds from the string
		string lfs = sass.substr(pos_right + 1);
		sass = sass.substr(0, pos_right + 1);

		// add newline as getline discharged it
		converter.whitespace += lfs + "\n";

		// maybe remove any leading whitespace
		if (PRETTIFY(converter) == 0)
		{
			// remove leading whitespace and update string
			size_t pos_left = sass.find_first_not_of(" \t\n\v\f\r");
			if (pos_left != string::npos) sass = sass.substr(pos_left);
		}

		// add flushed data
		scss += sass;

		// return string
		return scss;

	}
	// EO flush

	// process a line of the sass text
	string process (string& sass, converter& converter)
	{

		// resulting string
		string scss = "";

		// get postion of first meaningfull character in string
		size_t pos_left = sass.find_first_not_of(" \t\n\v\f\r");

		// special case for final run
		if (converter.end_of_file) pos_left = 0;

		// maybe has only whitespace
		if (pos_left == string::npos)
		{
			// just add complete whitespace
			converter.whitespace += sass + "\n";
		}
		// have meaningfull first char
		else
		{

			// extract and store indentation string
			string indent = sass.substr(0, pos_left);

			// line has less or same indentation
			// finalize previous open parser context
			if (indent.length() <= INDENT(converter).length())
			{

				// close multilinie comment
				if (IS_CSS_COMMENT(converter))
				{
					// check if comments will be stripped anyway
					if (!STRIP_COMMENT(converter)) scss += " */";
				}
				// close src comment comment
				else if (IS_SRC_COMMENT(converter))
				{
					// add a newline to avoid closer on same line
					// this would but the bracket in the comment node
					if (KEEP_COMMENT(converter)) scss += "\n";
				}
				// close css properties
				else if (converter.property)
				{
					// add semicolon unless in concat mode
					if (!converter.comma) scss += ";";
				}

				// reset comment state
				converter.comment = "";

			}

			// make sure we close every "higher" block
			while (indent.length() < INDENT(converter).length())
			{
				// pop stacked context
				converter.indents.pop();
				// print close bracket
				if (IS_PARSING(converter))
				{ scss += closer(converter); }
				else { scss += " */"; }
				// reset comment state
				converter.comment = "";
			}

			// check if we have sass property syntax
			if (sass.substr(pos_left, 1) == ":")
			{
				// get postion of first meaningfull char
				size_t pos_value = sass.find_first_of(" \t\n\v\f\r", pos_left);
				// create new string by interchanging the colon sign for property and value
				sass = indent + sass.substr(pos_left + 1, pos_value - pos_left - 1) + ":" + sass.substr(pos_value);
			}

			// replace some specific sass shorthand directives
			else if (sass.substr(pos_left, 1) == "=") { sass = indent + "@mixin " + sass.substr(pos_left + 1); }
			else if (sass.substr(pos_left, 1) == "+") { sass = indent + "@include " + sass.substr(pos_left + 1); }

			// add quotes for import if needed
			else if (sass.substr(pos_left, 7) == "@import")
			{
				// get positions for the actual import url
				size_t pos_import = sass.find_first_of(" \t\n\v\f\r", pos_left + 7);
				size_t pos_quote = sass.find_first_not_of(" \t\n\v\f\r", pos_import);
				// check if the url is quoted
				if (sass.substr(pos_quote, 1) != "\"")
				{
					// get position of the last char on the line
					size_t pos_end = sass.find_last_not_of(" \t\n\v\f\r");
					// add quotes around the full line after the import statement
					sass = sass.substr(0, pos_quote) + "\"" + sass.substr(pos_quote, pos_end - pos_quote + 1) + "\"";
				}
			}

			// check if current line starts a comment
			string open = sass.substr(pos_left, 2);

			// current line has more indentation
			if (indent.length() >= INDENT(converter).length())
			{
				// not in comment mode
				if (IS_PARSING(converter))
				{
					// probably a property
					converter.property = true;
				}
			}
			// current line has more indentation
			if (indent.length() > INDENT(converter).length())
			{
				// not in comment mode
				if (IS_PARSING(converter))
				{
					// print block opener
					scss += opener(converter);
					// push new stack context
					converter.indents.push("");
					// store block indentation
					INDENT(converter) = indent;
				}
				// is and will be a src comment
				else if (!IS_CSS_COMMENT(converter))
				{
					// scss does not allow multiline src comments
					// therefore add forward slashes to all lines
					sass[INDENT(converter).length()+0] = '/';
					// there is an edge case here if indentation
					// is minimal (will overwrite the fist char)
					sass[INDENT(converter).length()+1] = '/';
					// could code around that, but I dont' think
					// this will ever be the cause for any trouble
				}
			}

			// line is opening a new comment
			if (open == "/*" || open == "//")
			{
				// reset the property state
				converter.property = false;
				// close previous comment
				if (IS_CSS_COMMENT(converter) && open != "")
				{
					if (!STRIP_COMMENT(converter) && !CONVERT_COMMENT(converter)) scss += " */";
				}
				// force single line comments
				// into a correct css comment
				if (CONVERT_COMMENT(converter))
				{
					if (IS_PARSING(converter))
					{ sass[pos_left + 1] = '*'; }
				}
				// set comment flag
				converter.comment = open;

			}

			// flush data only under certain conditions
			if (!(
				// strip css and src comments if option is set
				(IS_COMMENT(converter) && STRIP_COMMENT(converter)) ||
				// strip src comment even if strip option is not set
				// but only if the keep src comment option is not set
				(IS_SRC_COMMENT(converter) && ! KEEP_COMMENT(converter))
			))
			{
				// flush data and buffer whitespace
				scss += flush(sass, converter);
			}

			// get postion of last meaningfull char
			size_t pos_right = sass.find_last_not_of(" \t\n\v\f\r");

			// check for invalid result
			if (pos_right != string::npos)
			{

				// get the last meaningfull char
				string close = sass.substr(pos_right, 1);

				// check if next line should be concatenated (list mode)
				converter.comma = IS_PARSING(converter) && close == ",";

				// check if we have more than
				// one meaningfull char
				if (pos_right > 0)
				{

					// get the last two chars from string
					string close = sass.substr(pos_right - 1, 2);
					// update parser status for expicitly closed comment
					if (close == "*/") converter.comment = "";

				}

			}
			// EO have meaningfull chars from end

		}
		// EO have meaningfull chars from start

		// return scss
		return scss;

	}
	// EO process

	// the main converter function for c++
	char* sass2scss (const string sass, const int options)
	{

		// local variables
		string line;
		string scss = "";
		const char delim = '\n';
		stringstream stream(sass);

		// create converter variable
		converter converter;
		// initialise all options
		converter.comma = false;
		converter.property = false;
		converter.end_of_file = false;
		converter.comment = "";
		converter.whitespace = "";
		converter.indents.push("");
		converter.options = options;

		// read line by line and process them
		while(std::getline(stream, line, delim))
		{ scss += process(line, converter); }

		// create mutable string
		string closer = "";
		// set the end of file flag
		converter.end_of_file = true;
		// process to close all open blocks
		scss += process(closer, converter);

		// allocate new memory on the heap
		// caller has to free it after use
		char * cstr = new char [scss.length()+1];
		// create a copy of the string
		strcpy (cstr, scss.c_str());
		// return pointer
		return &cstr[0];

	}
	// EO sass2scss

}
// EO namespace

// implement for c
extern "C"
{

	char* sass2scss (const char* sass, const int options)
	{
		return Sass::sass2scss(sass, options);
	}

}
<commit_msg>Fixes #3 (pseudo selectors failed to compile)<commit_after>// include library
#include <stack>
#include <string>
#include <cstring>
#include <sstream>
#include <iostream>

///*
//
// src comments: comments in sass syntax (staring with //)
// css comments: multiline comments in css syntax (starting with /*)
//
// KEEP_COMMENT: keep src comments in the resulting css code
// STRIP_COMMENT: strip out all comments (either src or css)
// CONVERT_COMMENT: convert all src comments to css comments
//
//*/

// our own header
#include "sass2scss.h"

// using std::string
using namespace std;

// add namespace for c++
namespace Sass
{

	// return the actual prettify value from options
	#define PRETTIFY(converter) (converter.options - (converter.options & 248))
	// query the options integer to check if the option is enables
	#define KEEP_COMMENT(converter) ((converter.options & SASS2SCSS_KEEP_COMMENT) == SASS2SCSS_KEEP_COMMENT)
	#define STRIP_COMMENT(converter) ((converter.options & SASS2SCSS_STRIP_COMMENT) == SASS2SCSS_STRIP_COMMENT)
	#define CONVERT_COMMENT(converter) ((converter.options & SASS2SCSS_CONVERT_COMMENT) == SASS2SCSS_CONVERT_COMMENT)

	// some makros to access the indentation stack
	#define INDENT(converter) (converter.indents.top())

	// some makros to query comment parser status
	#define IS_PARSING(converter) (converter.comment == "")
	#define IS_COMMENT(converter) (converter.comment != "")
	#define IS_SRC_COMMENT(converter) (converter.comment == "//" && ! CONVERT_COMMENT(converter))
	#define IS_CSS_COMMENT(converter) (converter.comment == "/*" || (converter.comment == "//" && CONVERT_COMMENT(converter)))

	// pretty printer helper function
	static string closer (const converter& converter)
	{
		return PRETTIFY(converter) == 0 ? " }" :
		     PRETTIFY(converter) <= 1 ? " }" :
		       "\n" + INDENT(converter) + "}";
	}

	// pretty printer helper function
	static string opener (const converter& converter)
	{
		return PRETTIFY(converter) == 0 ? " { " :
		     PRETTIFY(converter) <= 2 ? " {" :
		       "\n" + INDENT(converter) + "{";
	}

	// flush whitespace and print additional text, but
	// only print additional chars and buffer whitespace
	string flush (string& sass, converter& converter)
	{

		// return flushed
		string scss = "";

		// print whitespace buffer
		scss += PRETTIFY(converter) > 0 ?
		        converter.whitespace : "";
		// reset whitespace buffer
		converter.whitespace = "";

		// remove possible newlines from string
		size_t pos_right = sass.find_last_not_of("\n\r");
		if (pos_right == string::npos) return scss;

		// get the linefeeds from the string
		string lfs = sass.substr(pos_right + 1);
		sass = sass.substr(0, pos_right + 1);

		// add newline as getline discharged it
		converter.whitespace += lfs + "\n";

		// maybe remove any leading whitespace
		if (PRETTIFY(converter) == 0)
		{
			// remove leading whitespace and update string
			size_t pos_left = sass.find_first_not_of(" \t\n\v\f\r");
			if (pos_left != string::npos) sass = sass.substr(pos_left);
		}

		// add flushed data
		scss += sass;

		// return string
		return scss;

	}
	// EO flush

	// process a line of the sass text
	string process (string& sass, converter& converter)
	{

		// resulting string
		string scss = "";

		// get postion of first meaningfull character in string
		size_t pos_left = sass.find_first_not_of(" \t\n\v\f\r");

		// special case for final run
		if (converter.end_of_file) pos_left = 0;

		// maybe has only whitespace
		if (pos_left == string::npos)
		{
			// just add complete whitespace
			converter.whitespace += sass + "\n";
		}
		// have meaningfull first char
		else
		{

			// extract and store indentation string
			string indent = sass.substr(0, pos_left);

			// line has less or same indentation
			// finalize previous open parser context
			if (indent.length() <= INDENT(converter).length())
			{

				// close multilinie comment
				if (IS_CSS_COMMENT(converter))
				{
					// check if comments will be stripped anyway
					if (!STRIP_COMMENT(converter)) scss += " */";
				}
				// close src comment comment
				else if (IS_SRC_COMMENT(converter))
				{
					// add a newline to avoid closer on same line
					// this would but the bracket in the comment node
					if (KEEP_COMMENT(converter)) scss += "\n";
				}
				// close css properties
				else if (converter.property)
				{
					// add semicolon unless in concat mode
					if (!converter.comma) scss += ";";
				}

				// reset comment state
				converter.comment = "";

			}

			// make sure we close every "higher" block
			while (indent.length() < INDENT(converter).length())
			{
				// pop stacked context
				converter.indents.pop();
				// print close bracket
				if (IS_PARSING(converter))
				{ scss += closer(converter); }
				else { scss += " */"; }
				// reset comment state
				converter.comment = "";
			}

			// check if we have sass property syntax
			if (sass.substr(pos_left, 1) == ":")
			{
				// get postion of first whitespace char
				size_t pos_wspace = sass.find_first_of(" \t\n\v\f\r", pos_left);
				// assertion check for valid result
				if (pos_wspace != string::npos)
				{
					// get position of the first real property value char
					// pseudo selectors get this far, but have no actual value
					size_t pos_value =  sass.find_first_not_of(" \t\n\v\f\r", pos_wspace);
					// assertion check for valid result
					if (pos_value != string::npos)
					{
						// create new string by interchanging the colon sign for property and value
						sass = indent + sass.substr(pos_left + 1, pos_wspace - pos_left - 1) + ":" + sass.substr(pos_wspace);
					}
				}

			}

			// replace some specific sass shorthand directives
			else if (sass.substr(pos_left, 1) == "=") { sass = indent + "@mixin " + sass.substr(pos_left + 1); }
			else if (sass.substr(pos_left, 1) == "+") { sass = indent + "@include " + sass.substr(pos_left + 1); }

			// add quotes for import if needed
			else if (sass.substr(pos_left, 7) == "@import")
			{
				// get positions for the actual import url
				size_t pos_import = sass.find_first_of(" \t\n\v\f\r", pos_left + 7);
				size_t pos_quote = sass.find_first_not_of(" \t\n\v\f\r", pos_import);
				// check if the url is quoted
				if (sass.substr(pos_quote, 1) != "\"")
				{
					// get position of the last char on the line
					size_t pos_end = sass.find_last_not_of(" \t\n\v\f\r");
					// assertion check for valid result
					if (pos_end != string::npos)
					{
						// add quotes around the full line after the import statement
						sass = sass.substr(0, pos_quote) + "\"" + sass.substr(pos_quote, pos_end - pos_quote + 1) + "\"";
					}
				}
			}

			// check if current line starts a comment
			string open = sass.substr(pos_left, 2);

			// current line has more indentation
			if (indent.length() >= INDENT(converter).length())
			{
				// not in comment mode
				if (IS_PARSING(converter))
				{
					// probably a property
					converter.property = true;
				}
			}
			// current line has more indentation
			if (indent.length() > INDENT(converter).length())
			{
				// not in comment mode
				if (IS_PARSING(converter))
				{
					// print block opener
					scss += opener(converter);
					// push new stack context
					converter.indents.push("");
					// store block indentation
					INDENT(converter) = indent;
				}
				// is and will be a src comment
				else if (!IS_CSS_COMMENT(converter))
				{
					// scss does not allow multiline src comments
					// therefore add forward slashes to all lines
					sass[INDENT(converter).length()+0] = '/';
					// there is an edge case here if indentation
					// is minimal (will overwrite the fist char)
					sass[INDENT(converter).length()+1] = '/';
					// could code around that, but I dont' think
					// this will ever be the cause for any trouble
				}
			}

			// line is opening a new comment
			if (open == "/*" || open == "//")
			{
				// reset the property state
				converter.property = false;
				// close previous comment
				if (IS_CSS_COMMENT(converter) && open != "")
				{
					if (!STRIP_COMMENT(converter) && !CONVERT_COMMENT(converter)) scss += " */";
				}
				// force single line comments
				// into a correct css comment
				if (CONVERT_COMMENT(converter))
				{
					if (IS_PARSING(converter))
					{ sass[pos_left + 1] = '*'; }
				}
				// set comment flag
				converter.comment = open;

			}

			// flush data only under certain conditions
			if (!(
				// strip css and src comments if option is set
				(IS_COMMENT(converter) && STRIP_COMMENT(converter)) ||
				// strip src comment even if strip option is not set
				// but only if the keep src comment option is not set
				(IS_SRC_COMMENT(converter) && ! KEEP_COMMENT(converter))
			))
			{
				// flush data and buffer whitespace
				scss += flush(sass, converter);
			}

			// get postion of last meaningfull char
			size_t pos_right = sass.find_last_not_of(" \t\n\v\f\r");

			// check for invalid result
			if (pos_right != string::npos)
			{

				// get the last meaningfull char
				string close = sass.substr(pos_right, 1);

				// check if next line should be concatenated (list mode)
				converter.comma = IS_PARSING(converter) && close == ",";

				// check if we have more than
				// one meaningfull char
				if (pos_right > 0)
				{

					// get the last two chars from string
					string close = sass.substr(pos_right - 1, 2);
					// update parser status for expicitly closed comment
					if (close == "*/") converter.comment = "";

				}

			}
			// EO have meaningfull chars from end

		}
		// EO have meaningfull chars from start

		// return scss
		return scss;

	}
	// EO process

	// the main converter function for c++
	char* sass2scss (const string sass, const int options)
	{

		// local variables
		string line;
		string scss = "";
		const char delim = '\n';
		stringstream stream(sass);

		// create converter variable
		converter converter;
		// initialise all options
		converter.comma = false;
		converter.property = false;
		converter.end_of_file = false;
		converter.comment = "";
		converter.whitespace = "";
		converter.indents.push("");
		converter.options = options;

		// read line by line and process them
		while(std::getline(stream, line, delim))
		{ scss += process(line, converter); }

		// create mutable string
		string closer = "";
		// set the end of file flag
		converter.end_of_file = true;
		// process to close all open blocks
		scss += process(closer, converter);

		// allocate new memory on the heap
		// caller has to free it after use
		char * cstr = new char [scss.length()+1];
		// create a copy of the string
		strcpy (cstr, scss.c_str());
		// return pointer
		return &cstr[0];

	}
	// EO sass2scss

}
// EO namespace

// implement for c
extern "C"
{

	char* sass2scss (const char* sass, const int options)
	{
		return Sass::sass2scss(sass, options);
	}

}
<|endoftext|>


<commit_before>#include "stdafx.h"

#include <stdio.h>
#include <string>

#include "utilities_openGL.h"
//#include "shader.h"

namespace asdf {
    namespace util {

        /// I'm not entirely sure why these functions return true if there's an error, but whatever

        bool CheckShader(GLuint shader)
        {
            GLint glStatus;
            glGetShaderiv(shader, GL_COMPILE_STATUS, &glStatus);

            if(glStatus = GL_FALSE)
            {
                GLint error_length = 0;
                glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &error_length);

                std::string gl_error_str(error_length, '\n');
                glGetShaderInfoLog(shader, error_length, nullptr, &(gl_error_str[0]));

                fprintf(stderr, "Failed to compile shader!\n%s\n", gl_error_str.data());
                return true;
            }

            return false;
        }

        bool CheckGLError(GLuint shader)
        {
            if(shader != nullindex)
            {
                CheckShader(shader);
            }

            GLenum errCode;
            const GLubyte *errString;

            if ((errCode = glGetError()) != GL_NO_ERROR) {
                errString = gluErrorString(errCode);
                fprintf(stderr, "OpenGL Error: %s\n", errString);
                return true;
            }

            return false;
        }

        bool CheckGLError() { return CheckGLError(0xFFFFFFFF); }

    }
}<commit_msg>minor opengl error checking changes<commit_after>#include "stdafx.h"

#include <stdio.h>
#include <string>

#include "utilities_openGL.h"
//#include "shader.h"

namespace asdf {
    namespace util {

        /// I'm not entirely sure why these functions return true if there's an error, but whatever

        bool CheckShader(GLuint shader)
        {
            GLint glStatus;
            glGetShaderiv(shader, GL_COMPILE_STATUS, &glStatus);

            if(glStatus == GL_FALSE)
            {
                GLint error_length = 0;
                glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &error_length);

                std::string gl_error_str(error_length, '\n');
                glGetShaderInfoLog(shader, error_length, nullptr, &(gl_error_str[0]));

                fprintf(stderr, "Failed to compile shader!\n%s\n", gl_error_str.data());
                return true;
            }

            return false;
        }

        bool CheckGLError(GLuint shader)
        {
            bool had_error = false;

            if(shader != nullindex)
            {
                had_error = CheckShader(shader);
            }

            GLenum errCode = GL_NO_ERROR;

            while((errCode = glGetError()) != GL_NO_ERROR)
            {
                const GLubyte *errString;
                errString = gluErrorString(errCode);
                fprintf(stderr, "OpenGL Error: %s\n", errString);
                had_error = true;
            }

            return had_error;
        }

        bool CheckGLError() { return CheckGLError(0xFFFFFFFF); }

    }
}<|endoftext|>


<commit_before>#ifndef SAVE_STATE_H
# define SAVE_STATE_H
# pragma once

struct statebuf
{
  void* sp;
  void* label;
};

#if defined(__GNUC__)
static inline bool __attribute__((always_inline)) savestate(
  statebuf& ssb) noexcept
{
  bool r;

#if defined(i386) || defined(__i386) || defined(__i386__)
  asm volatile (
    "push %%ebp\n\t"
    "movl %%esp, %0\n\t" // store sp
    "movl $1f, %1\n\t" // store label
    "movb $0, %2\n\t" // return false
    "jmp 2f\n\t"
    "1:pop %%ebp\n\t"
    "movb $1, %2\n\t" // return true
    "2:"
    : "=m" (ssb.sp), "=m" (ssb.label), "=r" (r)
    :
    : "memory"
  );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
  asm volatile (
    "movq %%rsp, %0\n\t" // store sp
    "movq $1f, %1\n\t" // store label
    "movb $0, %2\n\t" // return false
    "jmp 2f\n\t"
    "1:movb $1, %2\n\t" // return true
    "2:"
    : "=m" (ssb.sp), "=m" (ssb.label), "=r" (r)
    :
    : "memory"
  );
#elif defined(__arm__)
  asm volatile (
    "push {fp}\n\t" // push fp
    "str sp, %0\n\t" // store sp
    "ldr r3, =1f\n\t" // load label into r0
    "str r3, %1\n\t" // store r0 into label
    "mov %2, $0\n\t" // store 0 into result
    "b 2f\n\t"
    "1:pop {fp}\n\t" // restore fp
    "mov %2, $1\n\t" // store 1 into result
    "2:"
    : "=m" (ssb.sp), "=m" (ssb.label), "=r" (r)
    :
    : "r3", "memory"
  );
#endif

  return r;
}
#elif defined(_MSC_VER)
__forceinline bool savestate(statebuf& ssb) noexcept
{
  bool r;

  __asm {
    push ebp
    mov ebx, ssb
    mov [ebx]ssb.sp, esp
    mov [ebx]ssb.label, offset _1f
    mov r, 0x0
    jmp _2f
    _1f: pop ebp
       mov r, 0x1
    _2f:
  }

  return r;
}
#else
# error "unsupported compiler"
#endif

#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
#define restorestate(SSB)          \
  asm volatile (                   \
    "movl %0, %%esp\n\t"           \
    "jmp *%1"                      \
    :                              \
    : "m" (SSB.sp), "m" (SSB.label)\
  );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
#define restorestate(SSB)          \
  asm volatile (                   \
    "movq %0, %%rsp\n\t"           \
    "jmp *%1"                      \
    :                              \
    : "m" (SSB.sp), "m" (SSB.label)\
  );
#elif defined(__arm__)
#define restorestate(SSB)          \
  asm volatile (                   \
    "ldr sp, %0\n\t"               \
    "ldr pc, %1"                   \
    :                              \
    : "m" (SSB.sp), "m" (SSB.label)\
  );
#else
# error "unsupported architecture"
#endif
#elif defined(_MSC_VER)
#define restorestate(SSB)   \
  __asm mov ebx, this       \
  __asm add ebx, [SSB]      \
  __asm mov esp, [ebx]SSB.sp\
  __asm jmp [ebx]SSB.label
#else
# error "unsupported compiler"
#endif

#endif // SAVE_STATE_H
<commit_msg>some fixes<commit_after>#ifndef SAVE_STATE_H
# define SAVE_STATE_H
# pragma once

struct statebuf
{
  void* sp;
  void* bp;
  void* label;
};

#if defined(__GNUC__)
static inline bool __attribute__((always_inline)) savestate(
  statebuf& ssb) noexcept
{
  bool r;

#if defined(i386) || defined(__i386) || defined(__i386__)
  asm volatile (
    "movl %%esp, %0\n\t" // store sp
    "movl %%ebp, %1\n\t" // store bp
    "movl $1f, %2\n\t" // store label
    "movb $0, %3\n\t" // return false
    "jmp 2f\n\t"
    "1:\n\t"
    "movb $1, %3\n\t" // return true
    "2:"
    : "=m" (ssb.sp), "=m" (ssb.bp), "=m" (ssb.label), "=r" (r)
    :
    : "memory"
  );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
  asm volatile (
    "movq %%rsp, %0\n\t" // store sp
    "movq %%rbp, %1\n\t" // store bp
    "movq $1f, %2\n\t" // store label
    "movb $0, %3\n\t" // return false
    "jmp 2f\n\t"
    "1:\n\t"
    "movb $1, %3\n\t" // return true
    "2:"
    : "=m" (ssb.sp), "=m" (ssb.bp), "=m" (ssb.label), "=r" (r)
    :
    : "memory"
  );
#elif defined(__arm__)
  asm volatile (
    "str sp, %0\n\t" // store sp
    "str fp, %1\n\t" // store fp
    "ldr r3, =1f\n\t"// load label into r3
    "str r3, %2\n\t" // store r3 into label
    "mov %3, $0\n\t" // store 0 into result
    "b 2f\n\t"
    "1:"             // restore fp
    "mov %3, $1\n\t" // store 1 into result
    "2:"
    : "=m" (ssb.sp), "=m" (ssb.bp), "=m" (ssb.label), "=r" (r)
    :
    : "r3", "memory"
  );
#endif

  return r;
}
#elif defined(_MSC_VER)
__forceinline bool savestate(statebuf& ssb) noexcept
{
  bool r;

  __asm {
    mov ebx, ssb
    mov [ebx]ssb.sp, esp
    mov [ebx]ssb.bp, ebp
    mov [ebx]ssb.label, offset _1f
    mov r, 0x0
    jmp _2f
    _1f:
    mov r, 0x1
    _2f:
  }

  return r;
}
#else
# error "unsupported compiler"
#endif

#if defined(__GNUC__)
#if defined(i386) || defined(__i386) || defined(__i386__)
#define restorestate(SSB)                        \
  asm volatile (                                 \
    "movl %0, %%esp\n\t"                         \
    "movl %1, %%ebp\n\t"                         \
    "jmp *%2"                                    \
    :                                            \
    : "m" (SSB.sp), "m" (SSB.bp), "m" (SSB.label)\
  );
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
#define restorestate(SSB)                        \
  asm volatile (                                 \
    "movq %0, %%rsp\n\t"                         \
    "movq %1, %%rbp\n\t"                         \
    "jmp *%2"                                    \
    :                                            \
    : "m" (SSB.sp), "m" (SSB.bp), "m" (SSB.label)\
  );
#elif defined(__arm__)
#define restorestate(SSB)          \
  asm volatile (                   \
    "ldr sp, %0\n\t"               \
    "ldr bp, %1\n\t"               \
    "ldr pc, %2"                   \
    :                              \
    : "m" (SSB.sp), "m" (SSB.bp), "m" (SSB.label)\
  );
#else
# error "unsupported architecture"
#endif
#elif defined(_MSC_VER)
#define restorestate(SSB)   \
  __asm mov ebx, this       \
  __asm add ebx, [SSB]      \
  __asm mov esp, [ebx]SSB.sp\
  __asm mov ebp, [ebx]SSB.bp\
  __asm jmp [ebx]SSB.label
#else
# error "unsupported compiler"
#endif

#endif // SAVE_STATE_H
<|endoftext|>


<commit_before>/*
 * Copyright 2011-2013 Blender Foundation
 *
 * 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 "util_system.h"
#include "util_types.h"

#ifdef _WIN32
#if(!defined(FREE_WINDOWS))
#include <intrin.h>
#endif
#include <windows.h>
#elif defined(__APPLE__)
#include <sys/sysctl.h>
#include <sys/types.h>
#else
#include <unistd.h>
#endif

CCL_NAMESPACE_BEGIN

int system_cpu_thread_count()
{
	static uint count = 0;

	if(count > 0)
		return count;

#ifdef _WIN32
	SYSTEM_INFO info;
	GetSystemInfo(&info);
	count = (uint)info.dwNumberOfProcessors;
#elif defined(__APPLE__)
	size_t len = sizeof(count);
	int mib[2] = { CTL_HW, HW_NCPU };

	sysctl(mib, 2, &count, &len, NULL, 0);
#else
	count = (uint)sysconf(_SC_NPROCESSORS_ONLN);
#endif

	if(count < 1)
		count = 1;

	return count;
}

#if !defined(_WIN32) || defined(FREE_WINDOWS)
static void __cpuid(int data[4], int selector)
{
#ifdef __x86_64__
	asm("cpuid" : "=a" (data[0]), "=b" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
#else
#ifdef __i386__
	asm("pushl %%ebx    \n\t"
		"cpuid          \n\t"
		"movl %%ebx, %1 \n\t"
		"popl %%ebx     \n\t" : "=a" (data[0]), "=r" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
#else
	data[0] = data[1] = data[2] = data[3] = 0;
#endif
#endif
}
#endif

static void replace_string(string& haystack, const string& needle, const string& other)
{
	size_t i;

	while((i = haystack.find(needle)) != string::npos)
		haystack.replace(i, needle.length(), other);
}

string system_cpu_brand_string()
{
	char buf[48];
	int result[4];

	__cpuid(result, 0x80000000);

	if(result[0] >= (int)0x80000004) {
		__cpuid((int*)(buf+0), 0x80000002);
		__cpuid((int*)(buf+16), 0x80000003);
		__cpuid((int*)(buf+32), 0x80000004);

		string brand = buf;

		/* make it a bit more presentable */
		replace_string(brand, "(TM)", "");
		replace_string(brand, "(R)", "");

		brand = string_strip(brand);

		return brand;
	}

	return "Unknown CPU";
}

int system_cpu_bits()
{
	return (sizeof(void*)*8);
}

#if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(_M_IX86)

struct CPUCapabilities {
	bool x64;
	bool mmx;
	bool sse;
	bool sse2;
	bool sse3;
	bool ssse3;
	bool sse41;
	bool sse42;
	bool sse4a;
	bool avx;
	bool avx2;
	bool xop;
	bool fma3;
	bool fma4;
	bool bmi1;
	bool bmi2;
};

static CPUCapabilities& system_cpu_capabilities()
{
	static CPUCapabilities caps;
	static bool caps_init = false;

	if(!caps_init) {
		int result[4], num; //, num_ex;

		memset(&caps, 0, sizeof(caps));

		__cpuid(result, 0);
		num = result[0];

#if 0
		__cpuid(result, 0x80000000);
		num_ex = result[0];
#endif

		if(num >= 1) {
			__cpuid(result, 0x00000001);
			caps.mmx = (result[3] & ((int)1 << 23)) != 0;
			caps.sse = (result[3] & ((int)1 << 25)) != 0;
			caps.sse2 = (result[3] & ((int)1 << 26)) != 0;
			caps.sse3 = (result[2] & ((int)1 <<  0)) != 0;

			caps.ssse3 = (result[2] & ((int)1 <<  9)) != 0;
			caps.sse41 = (result[2] & ((int)1 << 19)) != 0;
			caps.sse42 = (result[2] & ((int)1 << 20)) != 0;

			caps.fma3 = (result[2] & ((int)1 << 12)) != 0;
			caps.avx = false;
			bool os_uses_xsave_xrestore = (result[2] & ((int)1 << 27)) != 0;
			bool cpu_avx_support = (result[2] & ((int)1 << 28)) != 0;

			if( os_uses_xsave_xrestore && cpu_avx_support) {
				// Check if the OS will save the YMM registers
				uint32_t xcr_feature_mask;
#if defined(__GNUC__)
				int edx; /* not used */
				/* actual opcode for xgetbv */
				__asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (xcr_feature_mask) , "=d" (edx) : "c" (0) );
#elif defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
				xcr_feature_mask = (uint32_t)_xgetbv(_XCR_XFEATURE_ENABLED_MASK);  /* min VS2010 SP1 compiler is required */
#else
				xcr_feature_mask = 0;
#endif
				caps.avx = (xcr_feature_mask & 0x6) == 0x6;
			}

			__cpuid(result, 0x00000007);
			caps.bmi1 = (result[1] & ((int)1 << 3)) != 0;
			caps.bmi2 = (result[1] & ((int)1 << 8)) != 0;
			caps.avx2 = (result[1] & ((int)1 << 5)) != 0;
		}

#if 0
		if(num_ex >= 0x80000001) {
			__cpuid(result, 0x80000001);
			caps.x64 = (result[3] & ((int)1 << 29)) != 0;
			caps.sse4a = (result[2] & ((int)1 <<  6)) != 0;
			caps.fma4 = (result[2] & ((int)1 << 16)) != 0;
			caps.xop = (result[2] & ((int)1 << 11)) != 0;
		}
#endif

		caps_init = true;
	}

	return caps;
}

bool system_cpu_support_sse2()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2;
}

bool system_cpu_support_sse3()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3;
}

bool system_cpu_support_sse41()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41;
}

bool system_cpu_support_avx()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41 && caps.avx;
}
bool system_cpu_support_avx2()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41 && caps.avx && caps.avx2 && caps.fma3 && caps.bmi1 && caps.bmi2;
}
#else

bool system_cpu_support_sse2()
{
	return false;
}

bool system_cpu_support_sse3()
{
	return false;
}

bool system_cpu_support_sse41()
{
	return false;
}

bool system_cpu_support_avx()
{
	return false;
}
bool system_cpu_support_avx2()
{
	return false;
}

#endif

CCL_NAMESPACE_END

<commit_msg>Control CPU capabilities via environment variables<commit_after>/*
 * Copyright 2011-2013 Blender Foundation
 *
 * 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 "util_system.h"
#include "util_types.h"

#ifdef _WIN32
#if(!defined(FREE_WINDOWS))
#include <intrin.h>
#endif
#include <windows.h>
#elif defined(__APPLE__)
#include <sys/sysctl.h>
#include <sys/types.h>
#else
#include <unistd.h>
#endif

CCL_NAMESPACE_BEGIN

int system_cpu_thread_count()
{
	static uint count = 0;

	if(count > 0)
		return count;

#ifdef _WIN32
	SYSTEM_INFO info;
	GetSystemInfo(&info);
	count = (uint)info.dwNumberOfProcessors;
#elif defined(__APPLE__)
	size_t len = sizeof(count);
	int mib[2] = { CTL_HW, HW_NCPU };

	sysctl(mib, 2, &count, &len, NULL, 0);
#else
	count = (uint)sysconf(_SC_NPROCESSORS_ONLN);
#endif

	if(count < 1)
		count = 1;

	return count;
}

#if !defined(_WIN32) || defined(FREE_WINDOWS)
static void __cpuid(int data[4], int selector)
{
#ifdef __x86_64__
	asm("cpuid" : "=a" (data[0]), "=b" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
#else
#ifdef __i386__
	asm("pushl %%ebx    \n\t"
		"cpuid          \n\t"
		"movl %%ebx, %1 \n\t"
		"popl %%ebx     \n\t" : "=a" (data[0]), "=r" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
#else
	data[0] = data[1] = data[2] = data[3] = 0;
#endif
#endif
}
#endif

static void replace_string(string& haystack, const string& needle, const string& other)
{
	size_t i;

	while((i = haystack.find(needle)) != string::npos)
		haystack.replace(i, needle.length(), other);
}

string system_cpu_brand_string()
{
	char buf[48];
	int result[4];

	__cpuid(result, 0x80000000);

	if(result[0] >= (int)0x80000004) {
		__cpuid((int*)(buf+0), 0x80000002);
		__cpuid((int*)(buf+16), 0x80000003);
		__cpuid((int*)(buf+32), 0x80000004);

		string brand = buf;

		/* make it a bit more presentable */
		replace_string(brand, "(TM)", "");
		replace_string(brand, "(R)", "");

		brand = string_strip(brand);

		return brand;
	}

	return "Unknown CPU";
}

int system_cpu_bits()
{
	return (sizeof(void*)*8);
}

#if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(_M_IX86)

struct CPUCapabilities {
	bool x64;
	bool mmx;
	bool sse;
	bool sse2;
	bool sse3;
	bool ssse3;
	bool sse41;
	bool sse42;
	bool sse4a;
	bool avx;
	bool avx2;
	bool xop;
	bool fma3;
	bool fma4;
	bool bmi1;
	bool bmi2;
};

static void system_cpu_capabilities_override(CPUCapabilities *caps)
{
	/* Only capabilities which affects on cycles kernel. */
	if(getenv("CYCLES_CPU_NO_AVX2")) {
		caps->avx2 = false;
	}
	if(getenv("CYCLES_CPU_NO_AVX")) {
		caps->avx = false;
	}
	if(getenv("CYCLES_CPU_NO_SSE41")) {
		caps->sse41 = false;
	}
	if(getenv("CYCLES_CPU_NO_SSE3")) {
		caps->sse3 = false;
	}
	if(getenv("CYCLES_CPU_NO_SSE2")) {
		caps->sse2 = false;
	}
	if(getenv("CYCLES_CPU_NO_SSE")) {
		caps->sse = false;
	}
}

static CPUCapabilities& system_cpu_capabilities()
{
	static CPUCapabilities caps;
	static bool caps_init = false;

	if(!caps_init) {
		int result[4], num; //, num_ex;

		memset(&caps, 0, sizeof(caps));

		__cpuid(result, 0);
		num = result[0];

#if 0
		__cpuid(result, 0x80000000);
		num_ex = result[0];
#endif

		if(num >= 1) {
			__cpuid(result, 0x00000001);
			caps.mmx = (result[3] & ((int)1 << 23)) != 0;
			caps.sse = (result[3] & ((int)1 << 25)) != 0;
			caps.sse2 = (result[3] & ((int)1 << 26)) != 0;
			caps.sse3 = (result[2] & ((int)1 <<  0)) != 0;

			caps.ssse3 = (result[2] & ((int)1 <<  9)) != 0;
			caps.sse41 = (result[2] & ((int)1 << 19)) != 0;
			caps.sse42 = (result[2] & ((int)1 << 20)) != 0;

			caps.fma3 = (result[2] & ((int)1 << 12)) != 0;
			caps.avx = false;
			bool os_uses_xsave_xrestore = (result[2] & ((int)1 << 27)) != 0;
			bool cpu_avx_support = (result[2] & ((int)1 << 28)) != 0;

			if( os_uses_xsave_xrestore && cpu_avx_support) {
				// Check if the OS will save the YMM registers
				uint32_t xcr_feature_mask;
#if defined(__GNUC__)
				int edx; /* not used */
				/* actual opcode for xgetbv */
				__asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (xcr_feature_mask) , "=d" (edx) : "c" (0) );
#elif defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
				xcr_feature_mask = (uint32_t)_xgetbv(_XCR_XFEATURE_ENABLED_MASK);  /* min VS2010 SP1 compiler is required */
#else
				xcr_feature_mask = 0;
#endif
				caps.avx = (xcr_feature_mask & 0x6) == 0x6;
			}

			__cpuid(result, 0x00000007);
			caps.bmi1 = (result[1] & ((int)1 << 3)) != 0;
			caps.bmi2 = (result[1] & ((int)1 << 8)) != 0;
			caps.avx2 = (result[1] & ((int)1 << 5)) != 0;
		}

#if 0
		if(num_ex >= 0x80000001) {
			__cpuid(result, 0x80000001);
			caps.x64 = (result[3] & ((int)1 << 29)) != 0;
			caps.sse4a = (result[2] & ((int)1 <<  6)) != 0;
			caps.fma4 = (result[2] & ((int)1 << 16)) != 0;
			caps.xop = (result[2] & ((int)1 << 11)) != 0;
		}
#endif

		system_cpu_capabilities_override(&caps);

		caps_init = true;
	}

	return caps;
}

bool system_cpu_support_sse2()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2;
}

bool system_cpu_support_sse3()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3;
}

bool system_cpu_support_sse41()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41;
}

bool system_cpu_support_avx()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41 && caps.avx;
}
bool system_cpu_support_avx2()
{
	CPUCapabilities& caps = system_cpu_capabilities();
	return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3 && caps.sse41 && caps.avx && caps.avx2 && caps.fma3 && caps.bmi1 && caps.bmi2;
}
#else

bool system_cpu_support_sse2()
{
	return false;
}

bool system_cpu_support_sse3()
{
	return false;
}

bool system_cpu_support_sse41()
{
	return false;
}

bool system_cpu_support_avx()
{
	return false;
}
bool system_cpu_support_avx2()
{
	return false;
}

#endif

CCL_NAMESPACE_END

<|endoftext|>


<commit_before>#include "client.h"

namespace SleepyDiscord {
	void BaseDiscordClient::setError(int errorCode) {
		ErrorCode code = static_cast<ErrorCode>(errorCode);
		switch (code) {
		//HTTP Response/Error Codes
		case OK:                  onError(code, "The request completed successfully"                                             ); break;
		case CREATED:             onError(code, "The entity was created successfully"                                            ); break;
		case NO_CONTENT:          onError(code, "The request completed successfully but returned no content"                     ); break;
		case NOT_MODIFIED:        onError(code, "The entity was not modified (no action was taken)"                              ); break;
		case BAD_REQUEST:         onError(code, "The request was improperly formatted, or the server couldn't understand it"     ); break;
		case UNAUTHORIZED:        onError(code, "The Authorization header was missing or invalid"                                ); break;
		case FORBIDDEN:           onError(code, "The Authorization token you passed did not have permission to the resource"     ); break;
		case NOT_FOUND:           onError(code, "The resource at the location specified doesn't exist"                           ); break;
		case METHOD_NOT_ALLOWED:  onError(code, "The HTTP method used is not valid for the location specified"                   ); break;
		case TOO_MANY_REQUESTS:   onError(code, "You've made too many requests"                                                  ); break;
		case GATEWAY_UNAVAILABLE: onError(code, "There was not a gateway available to process your request. Wait a bit and retry"); break;
		default:
			if (500 <= errorCode && errorCode < 600) onError(code, "The server had an error processing your request (these are rare)");
			else onError(code, "Unknown");
			break;

		//JSON Error Response
		case 10001: onError(code, "Unknown account"                                                                                ); break;
		case 10002: onError(code, "Unknown application"                                                                                ); break;
		case 10003: onError(code, "Unknown channel"                                                                                ); break;
		case 10004: onError(code, "Unknown guild"                                                                                ); break;
		case 10005: onError(code, "Unknown integration"                                                                                ); break;
		case 10006: onError(code, "Unknown invite"                                                                                ); break;
		case 10007: onError(code, "Unknown member"                                                                                ); break;
		case 10008: onError(code, "Unknown message"                                                                                ); break;
		case 10009: onError(code, "Unknown overwrite"                                                                                ); break;
		case 10010: onError(code, "Unknown provider"                                                                                ); break;
		case 10011: onError(code, "Unknown role"                                                                                ); break;
		case 10012: onError(code, "Unknown token"                                                                                ); break;
		case 10013: onError(code, "Unknown user"                                                                                ); break;
		case 10014: onError(code, "Unknown Emoji"                                                                                ); break;
		case 20001: onError(code, "Bots cannot use this endpoint"                                                                                ); break;
		case 20002: onError(code, "Only bots can use this endpoint"                                                                               ); break;
		case 30001: onError(code, "Maximum number of guilds reached(100)"                                                                         ); break;
		case 30002: onError(code, "Maximum number of friends reached(1000)"                                                                       ); break;
		case 30003: onError(code, "Maximum number of pins reached(50)"                                                                            ); break;
		case 30005: onError(code, "Maximum number of guild roles reached(250)"                                                                    ); break;
		case 30010: onError(code, "Too many reactions"                                                                                ); break;
		case 40001: onError(code, "Unauthorized"                                                                                ); break;
		case 50001: onError(code, "Missing access"                                                                                ); break;
		case 50002: onError(code, "Invalid account type"                                                                                ); break;
		case 50003: onError(code, "Cannot execute action on a DM channel"                                                                         ); break;
		case 50004: onError(code, "Embed disabled"                                                                                ); break;
		case 50005: onError(code, "Cannot edit a message authored by another user"                                                                ); break;
		case 50006: onError(code, "Cannot send an empty message"                                                                                ); break;
		case 50007: onError(code, "Cannot send messages to this user"                                                                             ); break;
		case 50008: onError(code, "Cannot send messages in a voice channel"                                                                       ); break;
		case 50009: onError(code, "Channel verification level is too high"                                                                        ); break;
		case 50010: onError(code, "OAuth2 application does not have a bot"                                                                        ); break;
		case 50011: onError(code, "OAuth2 application limit reached"                                                                              ); break;
		case 50012: onError(code, "Invalid OAuth state"                                                                                ); break;
		case 50013: onError(code, "Missing permissions"                                                                                ); break;
		case 50014: onError(code, "Invalid authentication token"                                                                                ); break;
		case 50015: onError(code, "Note is too long"                                                                                ); break;
		case 50016: onError(code, "Provided too few or too many messages to delete.Must provide at least 2 and fewer than 100 messages to delete."); break;
		case 50019: onError(code, "A message can only be pinned to the channel it was sent in"                                                    ); break;
		case 50034: onError(code, "A message provided was too old to bulk delete"                                                                 ); break;
		case 90001: onError(code, "Reaction Blocked"                                                                                ); break;

		//Disconnections
		case UNKNOWN_ERROR:         onError(code, "unknown error - We're not sure what went wrong. Try reconnecting?"                                                                  ); break;
		case UNKNOWN_OPCODE:        onError(code, "unknown opcode - You sent an invalid Gateway OP Code. Don't do that!"                                                               ); break;
		case DECODE_ERROR:          onError(code, "decode error - You sent an invalid payload to us. Don't do that!"                                                                   ); break;
		case NOT_AUTHENTICATED:     onError(code, "not authenticated - You sent us a payload prior to identifying."                                                                    ); break;
		case AUTHENTICATION_FAILED: onError(code, "authentication failed - The account token sent with your identify payload is incorrect."                                            ); break;
		case ALREADY_AUTHENTICATED: onError(code, "already authenticated - You sent more than one identify payload. Don't do that!"                                                    ); break;
		case INVALID_SEQ:           onError(code, "invalid seq - The sequence sent when resuming the session was invalid. Reconnect and start a new session."                          ); break;
		case RATE_LIMITED:          onError(code, "rate limited - Woah nelly!You're sending payloads to us too quickly. Slow it down!"                                                 ); break;
		case SESSION_TIMEOUT:       onError(code, "session timeout - Your session timed out.Reconnect and start a new one."                                                            ); break;
		case INVALID_SHARD:         onError(code, "invalid shard - You sent us an invalid shard when identifying."                                                                     ); break;
		case SHARDING_REQUIRED:     onError(code, "sharding required - The session would have handled too many guilds - you are required to shard your connection in order to connect."); break;

		//Sleepy Errors
		case CONNECT_FAILED: onError(code, "Failed to connect to the Discord api after 4 trys"); break;
		case EVENT_UNKNOWN:  onError(code, "Unexpected or unknown event occurred"             ); break;
		case GATEWAY_FAILED: onError(code, "Could not get the gateway"                        ); break;
		}
	}
}<commit_msg>new error messages<commit_after>#include "client.h"

namespace SleepyDiscord {
	void BaseDiscordClient::setError(int errorCode) {
		ErrorCode code = static_cast<ErrorCode>(errorCode);
		switch (code) {
		case AN_ERROR : onError(code, "A wild error appeared"                                            ); break;
		case NO_ERRORS: onError(code, "Don't worry, everything is ok"                                    ); break;
		case OTHER    : onError(code, "The programmer was too lazy to give this error a code and message"); break;

		//HTTP Response/Error Codes
		case OK:                  onError(code, "The request completed successfully"                                             ); break;
		case CREATED:             onError(code, "The entity was created successfully"                                            ); break;
		case NO_CONTENT:          onError(code, "The request completed successfully but returned no content"                     ); break;
		case NOT_MODIFIED:        onError(code, "The entity was not modified (no action was taken)"                              ); break;
		case BAD_REQUEST:         onError(code, "The request was improperly formatted, or the server couldn't understand it"     ); break;
		case UNAUTHORIZED:        onError(code, "The Authorization header was missing or invalid"                                ); break;
		case FORBIDDEN:           onError(code, "The Authorization token you passed did not have permission to the resource"     ); break;
		case NOT_FOUND:           onError(code, "The resource at the location specified doesn't exist"                           ); break;
		case METHOD_NOT_ALLOWED:  onError(code, "The HTTP method used is not valid for the location specified"                   ); break;
		case TOO_MANY_REQUESTS:   onError(code, "You've made too many requests"                                                  ); break;
		case GATEWAY_UNAVAILABLE: onError(code, "There was not a gateway available to process your request. Wait a bit and retry"); break;
		default:
			if (500 <= errorCode && errorCode < 600) onError(code, "The server had an error processing your request (these are rare)");
			else onError(code, "Unknown");
			break;

		//JSON Error Response
		case 10001: onError(code, "Unknown account"                                                                                ); break;
		case 10002: onError(code, "Unknown application"                                                                                ); break;
		case 10003: onError(code, "Unknown channel"                                                                                ); break;
		case 10004: onError(code, "Unknown guild"                                                                                ); break;
		case 10005: onError(code, "Unknown integration"                                                                                ); break;
		case 10006: onError(code, "Unknown invite"                                                                                ); break;
		case 10007: onError(code, "Unknown member"                                                                                ); break;
		case 10008: onError(code, "Unknown message"                                                                                ); break;
		case 10009: onError(code, "Unknown overwrite"                                                                                ); break;
		case 10010: onError(code, "Unknown provider"                                                                                ); break;
		case 10011: onError(code, "Unknown role"                                                                                ); break;
		case 10012: onError(code, "Unknown token"                                                                                ); break;
		case 10013: onError(code, "Unknown user"                                                                                ); break;
		case 10014: onError(code, "Unknown Emoji"                                                                                ); break;
		case 20001: onError(code, "Bots cannot use this endpoint"                                                                                ); break;
		case 20002: onError(code, "Only bots can use this endpoint"                                                                               ); break;
		case 30001: onError(code, "Maximum number of guilds reached(100)"                                                                         ); break;
		case 30002: onError(code, "Maximum number of friends reached(1000)"                                                                       ); break;
		case 30003: onError(code, "Maximum number of pins reached(50)"                                                                            ); break;
		case 30005: onError(code, "Maximum number of guild roles reached(250)"                                                                    ); break;
		case 30010: onError(code, "Too many reactions"                                                                                ); break;
		case 40001: onError(code, "Unauthorized"                                                                                ); break;
		case 50001: onError(code, "Missing access"                                                                                ); break;
		case 50002: onError(code, "Invalid account type"                                                                                ); break;
		case 50003: onError(code, "Cannot execute action on a DM channel"                                                                         ); break;
		case 50004: onError(code, "Embed disabled"                                                                                ); break;
		case 50005: onError(code, "Cannot edit a message authored by another user"                                                                ); break;
		case 50006: onError(code, "Cannot send an empty message"                                                                                ); break;
		case 50007: onError(code, "Cannot send messages to this user"                                                                             ); break;
		case 50008: onError(code, "Cannot send messages in a voice channel"                                                                       ); break;
		case 50009: onError(code, "Channel verification level is too high"                                                                        ); break;
		case 50010: onError(code, "OAuth2 application does not have a bot"                                                                        ); break;
		case 50011: onError(code, "OAuth2 application limit reached"                                                                              ); break;
		case 50012: onError(code, "Invalid OAuth state"                                                                                ); break;
		case 50013: onError(code, "Missing permissions"                                                                                ); break;
		case 50014: onError(code, "Invalid authentication token"                                                                                ); break;
		case 50015: onError(code, "Note is too long"                                                                                ); break;
		case 50016: onError(code, "Provided too few or too many messages to delete.Must provide at least 2 and fewer than 100 messages to delete."); break;
		case 50019: onError(code, "A message can only be pinned to the channel it was sent in"                                                    ); break;
		case 50034: onError(code, "A message provided was too old to bulk delete"                                                                 ); break;
		case 90001: onError(code, "Reaction Blocked"                                                                                ); break;

		//Disconnections
		case UNKNOWN_ERROR:         onError(code, "unknown error - We're not sure what went wrong. Try reconnecting?"                                                                  ); break;
		case UNKNOWN_OPCODE:        onError(code, "unknown opcode - You sent an invalid Gateway OP Code. Don't do that!"                                                               ); break;
		case DECODE_ERROR:          onError(code, "decode error - You sent an invalid payload to us. Don't do that!"                                                                   ); break;
		case NOT_AUTHENTICATED:     onError(code, "not authenticated - You sent us a payload prior to identifying."                                                                    ); break;
		case AUTHENTICATION_FAILED: onError(code, "authentication failed - The account token sent with your identify payload is incorrect."                                            ); break;
		case ALREADY_AUTHENTICATED: onError(code, "already authenticated - You sent more than one identify payload. Don't do that!"                                                    ); break;
		case INVALID_SEQ:           onError(code, "invalid seq - The sequence sent when resuming the session was invalid. Reconnect and start a new session."                          ); break;
		case RATE_LIMITED:          onError(code, "rate limited - Woah nelly!You're sending payloads to us too quickly. Slow it down!"                                                 ); break;
		case SESSION_TIMEOUT:       onError(code, "session timeout - Your session timed out.Reconnect and start a new one."                                                            ); break;
		case INVALID_SHARD:         onError(code, "invalid shard - You sent us an invalid shard when identifying."                                                                     ); break;
		case SHARDING_REQUIRED:     onError(code, "sharding required - The session would have handled too many guilds - you are required to shard your connection in order to connect."); break;

		//Sleepy Errors
		case CONNECT_FAILED: onError(code, "Failed to connect to the Discord api after 4 trys"); break;
		case EVENT_UNKNOWN:  onError(code, "Unexpected or unknown event occurred"             ); break;
		case GATEWAY_FAILED: onError(code, "Could not get the gateway"                        ); break;
		}
	}
}<|endoftext|>


<commit_before>//===-- Broadcaster.cpp -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/Broadcaster.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/StreamString.h"
#include "lldb/lldb-private-log.h"

using namespace lldb;
using namespace lldb_private;

Broadcaster::Broadcaster (const char *name) :
    m_broadcaster_name (name),
    m_listeners (),
    m_listeners_mutex (Mutex::eMutexTypeRecursive),
    m_hijacking_listener(NULL),
    m_hijacking_mask(UINT32_MAX)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
    if (log)
        log->Printf ("%p Broadcaster::Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString());

}

Broadcaster::~Broadcaster()
{
    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
    if (log)
        log->Printf ("%p Broadcaster::~Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString());

    // Scope for "listeners_locker"
    {
        Mutex::Locker listeners_locker(m_listeners_mutex);

        // Make sure the listener forgets about this broadcaster. We do
        // this in the broadcaster in case the broadcaster object initiates
        // the removal.

        collection::iterator pos, end = m_listeners.end();
        for (pos = m_listeners.begin(); pos != end; ++pos)
            pos->first->BroadcasterWillDestruct (this);

        m_listeners.clear();
    }
}

const ConstString &
Broadcaster::GetBroadcasterName ()
{
    return m_broadcaster_name;
}

bool
Broadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const
{
    uint32_t num_names_added = 0;
    if (event_mask && !m_event_names.empty())
    {
        event_names_map::const_iterator end = m_event_names.end();
        for (uint32_t bit=1u, mask=event_mask; mask != 0 && bit != 0; bit <<= 1, mask >>= 1)
        {
            if (mask & 1)
            {
                event_names_map::const_iterator pos = m_event_names.find(bit);
                if (pos != end)
                {
                    if (num_names_added > 0)
                        s.PutCString(", ");

                    if (prefix_with_broadcaster_name)
                    {
                        s.PutCString (m_broadcaster_name.GetCString());
                        s.PutChar('.');
                    }
                    s.PutCString(pos->second.c_str());
                    ++num_names_added;
                }
            }
        }
    }
    return num_names_added > 0;
}

void
Broadcaster::AddInitialEventsToListener (Listener *listener, uint32_t requested_events)
{

}

uint32_t
Broadcaster::AddListener (Listener* listener, uint32_t event_mask)
{
    Mutex::Locker locker(m_listeners_mutex);
    collection::iterator pos, end = m_listeners.end();

    collection::iterator existing_pos = end;
    // See if we already have this listener, and if so, update its mask
    uint32_t taken_event_types = 0;
    for (pos = m_listeners.begin(); pos != end; ++pos)
    {
        if (pos->first == listener)
            existing_pos = pos;
    // For now don't descriminate on who gets what
    // FIXME: Implement "unique listener for this bit" mask
    //  taken_event_types |= pos->second;
    }

    // Each event bit in a Broadcaster object can only be used
    // by one listener
    uint32_t available_event_types = ~taken_event_types & event_mask;

    if (available_event_types)
    {
        // If we didn't find our listener, add it
        if (existing_pos == end)
        {
            // Grant a new listener the available event bits
            m_listeners.push_back(std::make_pair(listener, available_event_types));
        }
        else
        {
            // Grant the existing listener the available event bits
            existing_pos->second |= available_event_types;
        }

        // Individual broadcasters decide whether they have outstanding data when a
        // listener attaches, and insert it into the listener with this method.

        AddInitialEventsToListener (listener, available_event_types);
    }

    // Return the event bits that were granted to the listener
    return available_event_types;
}

bool
Broadcaster::EventTypeHasListeners (uint32_t event_type)
{
    Mutex::Locker locker (m_listeners_mutex);

    if (m_hijacking_listener != NULL && event_type & m_hijacking_mask)
        return true;

    if (m_listeners.empty())
        return false;

    collection::iterator pos, end = m_listeners.end();
    for (pos = m_listeners.begin(); pos != end; ++pos)
    {
        if (pos->second & event_type)
            return true;
    }
    return false;
}

bool
Broadcaster::RemoveListener (Listener* listener, uint32_t event_mask)
{
    Mutex::Locker locker(m_listeners_mutex);
    collection::iterator pos, end = m_listeners.end();
    // See if we already have this listener, and if so, update its mask
    for (pos = m_listeners.begin(); pos != end; ++pos)
    {
        if (pos->first == listener)
        {
            // Relinquish all event bits in "event_mask"
            pos->second &= ~event_mask;
            // If all bits have been relinquished then remove this listener
            if (pos->second == 0)
                m_listeners.erase (pos);
            return true;
        }
    }
    return false;
}

void
Broadcaster::BroadcastEvent (EventSP &event_sp)
{
    return PrivateBroadcastEvent (event_sp, false);
}

void
Broadcaster::BroadcastEventIfUnique (EventSP &event_sp)
{
    return PrivateBroadcastEvent (event_sp, true);
}

void
Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
{
    // Can't add a NULL event...
    if (event_sp.get() == NULL)
        return;

    // Update the broadcaster on this event
    event_sp->SetBroadcaster (this);

    const uint32_t event_type = event_sp->GetType();

    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
    if (log)
    {
        StreamString event_description;
        event_sp->Dump  (&event_description);
        log->Printf ("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, unique =%i)",
                     this,
                     m_broadcaster_name.AsCString(""),
                     event_description.GetData(),
                     unique);
    }

    if (m_hijacking_listener != NULL && m_hijacking_mask & event_type)
    {
        if (unique && m_hijacking_listener->PeekAtNextEventForBroadcasterWithType (this, event_type))
            return;
        m_hijacking_listener->AddEvent (event_sp);
    }
    else
    {
        Mutex::Locker event_types_locker(m_listeners_mutex);
        collection::iterator pos, end = m_listeners.end();

        // Iterate through all listener/mask pairs
        for (pos = m_listeners.begin(); pos != end; ++pos)
        {
            // If the listener's mask matches any bits that we just set, then
            // put the new event on its event queue.
            if (event_type & pos->second)
            {
                if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (this, event_type))
                    continue;
                pos->first->AddEvent (event_sp);
            }
        }
    }
}

void
Broadcaster::BroadcastEvent (uint32_t event_type, EventData *event_data)
{
    EventSP event_sp (new Event (event_type, event_data));
    PrivateBroadcastEvent (event_sp, false);
}

void
Broadcaster::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data)
{
    EventSP event_sp (new Event (event_type, event_data));
    PrivateBroadcastEvent (event_sp, true);
}

bool
Broadcaster::HijackBroadcaster (Listener *listener, uint32_t event_mask)
{
    Mutex::Locker event_types_locker(m_listeners_mutex);

    if (m_hijacking_listener != NULL)
        return false;

    m_hijacking_listener = listener;
    m_hijacking_mask = event_mask;
    return true;
}

void
Broadcaster::RestoreBroadcaster ()
{
    Mutex::Locker event_types_locker(m_listeners_mutex);
    m_hijacking_listener = NULL;
    m_hijacking_mask = 0;
}

<commit_msg>Broadcaster::AddListener(): Bail out early if the passed in Listener pointer is NULL, instead of registering a NULL listener and to crash later.<commit_after>//===-- Broadcaster.cpp -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/Broadcaster.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/StreamString.h"
#include "lldb/lldb-private-log.h"

using namespace lldb;
using namespace lldb_private;

Broadcaster::Broadcaster (const char *name) :
    m_broadcaster_name (name),
    m_listeners (),
    m_listeners_mutex (Mutex::eMutexTypeRecursive),
    m_hijacking_listener(NULL),
    m_hijacking_mask(UINT32_MAX)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
    if (log)
        log->Printf ("%p Broadcaster::Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString());

}

Broadcaster::~Broadcaster()
{
    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
    if (log)
        log->Printf ("%p Broadcaster::~Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString());

    // Scope for "listeners_locker"
    {
        Mutex::Locker listeners_locker(m_listeners_mutex);

        // Make sure the listener forgets about this broadcaster. We do
        // this in the broadcaster in case the broadcaster object initiates
        // the removal.

        collection::iterator pos, end = m_listeners.end();
        for (pos = m_listeners.begin(); pos != end; ++pos)
            pos->first->BroadcasterWillDestruct (this);

        m_listeners.clear();
    }
}

const ConstString &
Broadcaster::GetBroadcasterName ()
{
    return m_broadcaster_name;
}

bool
Broadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const
{
    uint32_t num_names_added = 0;
    if (event_mask && !m_event_names.empty())
    {
        event_names_map::const_iterator end = m_event_names.end();
        for (uint32_t bit=1u, mask=event_mask; mask != 0 && bit != 0; bit <<= 1, mask >>= 1)
        {
            if (mask & 1)
            {
                event_names_map::const_iterator pos = m_event_names.find(bit);
                if (pos != end)
                {
                    if (num_names_added > 0)
                        s.PutCString(", ");

                    if (prefix_with_broadcaster_name)
                    {
                        s.PutCString (m_broadcaster_name.GetCString());
                        s.PutChar('.');
                    }
                    s.PutCString(pos->second.c_str());
                    ++num_names_added;
                }
            }
        }
    }
    return num_names_added > 0;
}

void
Broadcaster::AddInitialEventsToListener (Listener *listener, uint32_t requested_events)
{

}

uint32_t
Broadcaster::AddListener (Listener* listener, uint32_t event_mask)
{
    if (listener == NULL)
        return 0;

    Mutex::Locker locker(m_listeners_mutex);
    collection::iterator pos, end = m_listeners.end();

    collection::iterator existing_pos = end;
    // See if we already have this listener, and if so, update its mask
    uint32_t taken_event_types = 0;
    for (pos = m_listeners.begin(); pos != end; ++pos)
    {
        if (pos->first == listener)
            existing_pos = pos;
    // For now don't descriminate on who gets what
    // FIXME: Implement "unique listener for this bit" mask
    //  taken_event_types |= pos->second;
    }

    // Each event bit in a Broadcaster object can only be used
    // by one listener
    uint32_t available_event_types = ~taken_event_types & event_mask;

    if (available_event_types)
    {
        // If we didn't find our listener, add it
        if (existing_pos == end)
        {
            // Grant a new listener the available event bits
            m_listeners.push_back(std::make_pair(listener, available_event_types));
        }
        else
        {
            // Grant the existing listener the available event bits
            existing_pos->second |= available_event_types;
        }

        // Individual broadcasters decide whether they have outstanding data when a
        // listener attaches, and insert it into the listener with this method.

        AddInitialEventsToListener (listener, available_event_types);
    }

    // Return the event bits that were granted to the listener
    return available_event_types;
}

bool
Broadcaster::EventTypeHasListeners (uint32_t event_type)
{
    Mutex::Locker locker (m_listeners_mutex);

    if (m_hijacking_listener != NULL && event_type & m_hijacking_mask)
        return true;

    if (m_listeners.empty())
        return false;

    collection::iterator pos, end = m_listeners.end();
    for (pos = m_listeners.begin(); pos != end; ++pos)
    {
        if (pos->second & event_type)
            return true;
    }
    return false;
}

bool
Broadcaster::RemoveListener (Listener* listener, uint32_t event_mask)
{
    Mutex::Locker locker(m_listeners_mutex);
    collection::iterator pos, end = m_listeners.end();
    // See if we already have this listener, and if so, update its mask
    for (pos = m_listeners.begin(); pos != end; ++pos)
    {
        if (pos->first == listener)
        {
            // Relinquish all event bits in "event_mask"
            pos->second &= ~event_mask;
            // If all bits have been relinquished then remove this listener
            if (pos->second == 0)
                m_listeners.erase (pos);
            return true;
        }
    }
    return false;
}

void
Broadcaster::BroadcastEvent (EventSP &event_sp)
{
    return PrivateBroadcastEvent (event_sp, false);
}

void
Broadcaster::BroadcastEventIfUnique (EventSP &event_sp)
{
    return PrivateBroadcastEvent (event_sp, true);
}

void
Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
{
    // Can't add a NULL event...
    if (event_sp.get() == NULL)
        return;

    // Update the broadcaster on this event
    event_sp->SetBroadcaster (this);

    const uint32_t event_type = event_sp->GetType();

    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
    if (log)
    {
        StreamString event_description;
        event_sp->Dump  (&event_description);
        log->Printf ("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, unique =%i)",
                     this,
                     m_broadcaster_name.AsCString(""),
                     event_description.GetData(),
                     unique);
    }

    if (m_hijacking_listener != NULL && m_hijacking_mask & event_type)
    {
        if (unique && m_hijacking_listener->PeekAtNextEventForBroadcasterWithType (this, event_type))
            return;
        m_hijacking_listener->AddEvent (event_sp);
    }
    else
    {
        Mutex::Locker event_types_locker(m_listeners_mutex);
        collection::iterator pos, end = m_listeners.end();

        // Iterate through all listener/mask pairs
        for (pos = m_listeners.begin(); pos != end; ++pos)
        {
            // If the listener's mask matches any bits that we just set, then
            // put the new event on its event queue.
            if (event_type & pos->second)
            {
                if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (this, event_type))
                    continue;
                pos->first->AddEvent (event_sp);
            }
        }
    }
}

void
Broadcaster::BroadcastEvent (uint32_t event_type, EventData *event_data)
{
    EventSP event_sp (new Event (event_type, event_data));
    PrivateBroadcastEvent (event_sp, false);
}

void
Broadcaster::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data)
{
    EventSP event_sp (new Event (event_type, event_data));
    PrivateBroadcastEvent (event_sp, true);
}

bool
Broadcaster::HijackBroadcaster (Listener *listener, uint32_t event_mask)
{
    Mutex::Locker event_types_locker(m_listeners_mutex);

    if (m_hijacking_listener != NULL)
        return false;

    m_hijacking_listener = listener;
    m_hijacking_mask = event_mask;
    return true;
}

void
Broadcaster::RestoreBroadcaster ()
{
    Mutex::Locker event_types_locker(m_listeners_mutex);
    m_hijacking_listener = NULL;
    m_hijacking_mask = 0;
}

<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: MOL2File_test.C,v 1.10 2003/02/20 06:50:37 oliver Exp $

#include <BALL/CONCEPT/classTest.h>

///////////////////////////

#include <BALL/FORMAT/MOL2File.h>
#include <BALL/KERNEL/forEach.h>
#include <BALL/KERNEL/PTE.h>
#include <BALL/KERNEL/atom.h>
#include <BALL/KERNEL/bond.h>
#include <BALL/KERNEL/system.h>
#include <BALL/KERNEL/molecule.h>
#include <BALL/MATHS/vector3.h>

///////////////////////////

START_TEST(MOL2File, "$Id: MOL2File_test.C,v 1.10 2003/02/20 06:50:37 oliver Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;

MOL2File* mf = 0;
CHECK(MOL2File::MOL2File())
	mf = new MOL2File;
	TEST_NOT_EQUAL(mf, 0)
RESULT

CHECK(MOL2File::~MOL2File())
	delete mf;
RESULT

CHECK(MOL2File::read(System& system))
	MOL2File f("data/AAG.mol2");
	System system;
	f.read(system);
	TEST_EQUAL(system.countAtoms(), 30)
	TEST_EQUAL(system.countResidues(), 3)
	Size number_of_bonds = 0;
	Atom::BondIterator bond_it;
	AtomIterator atom_it;
	BALL_FOREACH_BOND(system, atom_it, bond_it)
	{
		number_of_bonds++;
	}
	TEST_EQUAL(number_of_bonds, 29)
RESULT

CHECK(MOL2File::MOL2File(const String& filename, File::OpenMode open_mode))
	MOL2File f("data/AAG.mol2", std::ios::in);
	System system;
	f.read(system);
	TEST_EQUAL(system.countAtoms(), 30)
	TEST_EQUAL(system.countResidues(), 3)
	Size number_of_bonds = 0;
	Atom::BondIterator bond_it;
	AtomIterator atom_it;
	BALL_FOREACH_BOND(system, atom_it, bond_it)
	{
		number_of_bonds++;
	}
	TEST_EQUAL(number_of_bonds, 29)

	// writing is tested below...
RESULT

CHECK(MOL2File::write(const System& system))
  Molecule* m = new Molecule;
	m->setName("MOL");
	System S;
	S.setName("SYSTEM");
	S.insert(*m);
	Atom* a1 = new Atom();
	Atom* a2 = new Atom();
	m->insert(*a1);
	m->insert(*a2);

	a1->setName("A1");
	a1->setElement(PTE[Element::N]);
	a1->setCharge(0.5);
	a1->setPosition(Vector3(0.1, 0.2, 0.3));

	a2->setName("A2");
	a2->setElement(PTE[Element::O]);
	a2->setCharge(-0.5);
	a2->setPosition(Vector3(0.5, 0.6, 0.7));

	a1->createBond(*a2);
	a1->getBond(*a2)->setOrder(Bond::ORDER__DOUBLE);

	String filename;
	NEW_TMP_FILE(filename)
	MOL2File f(filename, std::ios::out);
	f.write(S);
	f.close();

	TEST_FILE_REGEXP(filename.c_str(), "data/MOL2File_test.mol2")
RESULT

CHECK(MOL2File::MOL2File& operator >> (System& system))
  MOL2File f("data/AAG.mol2");
	System S;
	f >> S;
	f.close();
	TEST_EQUAL(S.countAtoms(), 30)
RESULT

CHECK(MOL2File::MOL2File& operator << (const System& system))
  Molecule* m = new Molecule;
	m->setName("MOL");
	System S;
	S.setName("SYSTEM");
	S.insert(*m);
	Atom* a1 = new Atom();
	Atom* a2 = new Atom();
	m->insert(*a1);
	m->insert(*a2);

	a1->setName("A1");
	a1->setElement(PTE[Element::N]);
	a1->setCharge(0.5);
	a1->setPosition(Vector3(0.1, 0.2, 0.3));

	a2->setName("A2");
	a2->setElement(PTE[Element::O]);
	a2->setCharge(-0.5);
	a2->setPosition(Vector3(0.5, 0.6, 0.7));

	a1->createBond(*a2);
	a1->getBond(*a2)->setOrder(Bond::ORDER__DOUBLE);

	String filename;
	NEW_TMP_FILE(filename)
	MOL2File f(filename, std::ios::out);
	f << S;
	f.close();

	TEST_FILE_REGEXP(filename.c_str(), "data/MOL2File_test.mol2")
RESULT

CHECK(Bug #11)
	MOL2File f("data/MOL2File_test_bug11.mol2");
	System S;
	f >> S;
	f.close();
	TEST_EQUAL(S.countAtoms(), 15)
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<commit_msg>Added test for reading of triple bonds.<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: MOL2File_test.C,v 1.11 2003/03/03 09:53:27 anhi Exp $

#include <BALL/CONCEPT/classTest.h>

///////////////////////////

#include <BALL/FORMAT/MOL2File.h>
#include <BALL/KERNEL/forEach.h>
#include <BALL/KERNEL/PTE.h>
#include <BALL/KERNEL/atom.h>
#include <BALL/KERNEL/bond.h>
#include <BALL/KERNEL/system.h>
#include <BALL/KERNEL/molecule.h>
#include <BALL/MATHS/vector3.h>

///////////////////////////

START_TEST(MOL2File, "$Id: MOL2File_test.C,v 1.11 2003/03/03 09:53:27 anhi Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;

MOL2File* mf = 0;
CHECK(MOL2File::MOL2File())
	mf = new MOL2File;
	TEST_NOT_EQUAL(mf, 0)
RESULT

CHECK(MOL2File::~MOL2File())
	delete mf;
RESULT

CHECK(MOL2File::read(System& system))
	MOL2File f("data/AAG.mol2");
	System system;
	f.read(system);
	TEST_EQUAL(system.countAtoms(), 30)
	TEST_EQUAL(system.countResidues(), 3)
	Size number_of_bonds = 0;
	Atom::BondIterator bond_it;
	AtomIterator atom_it;
	BALL_FOREACH_BOND(system, atom_it, bond_it)
	{
		number_of_bonds++;
	}
	TEST_EQUAL(number_of_bonds, 29)
RESULT

CHECK(MOL2File::MOL2File(const String& filename, File::OpenMode open_mode))
	MOL2File f("data/AAG.mol2", std::ios::in);
	System system;
	f.read(system);
	TEST_EQUAL(system.countAtoms(), 30)
	TEST_EQUAL(system.countResidues(), 3)
	Size number_of_bonds = 0;
	Atom::BondIterator bond_it;
	AtomIterator atom_it;
	BALL_FOREACH_BOND(system, atom_it, bond_it)
	{
		number_of_bonds++;
	}
	TEST_EQUAL(number_of_bonds, 29)

	// writing is tested below...
RESULT

CHECK(MOL2File::write(const System& system))
  Molecule* m = new Molecule;
	m->setName("MOL");
	System S;
	S.setName("SYSTEM");
	S.insert(*m);
	Atom* a1 = new Atom();
	Atom* a2 = new Atom();
	m->insert(*a1);
	m->insert(*a2);

	a1->setName("A1");
	a1->setElement(PTE[Element::N]);
	a1->setCharge(0.5);
	a1->setPosition(Vector3(0.1, 0.2, 0.3));

	a2->setName("A2");
	a2->setElement(PTE[Element::O]);
	a2->setCharge(-0.5);
	a2->setPosition(Vector3(0.5, 0.6, 0.7));

	a1->createBond(*a2);
	a1->getBond(*a2)->setOrder(Bond::ORDER__DOUBLE);

	String filename;
	NEW_TMP_FILE(filename)
	MOL2File f(filename, std::ios::out);
	f.write(S);
	f.close();

	TEST_FILE_REGEXP(filename.c_str(), "data/MOL2File_test.mol2")
RESULT

CHECK(MOL2File::MOL2File& operator >> (System& system))
  MOL2File f("data/AAG.mol2");
	System S;
	f >> S;
	f.close();
	TEST_EQUAL(S.countAtoms(), 30)
RESULT

CHECK(MOL2File::MOL2File& operator << (const System& system))
  Molecule* m = new Molecule;
	m->setName("MOL");
	System S;
	S.setName("SYSTEM");
	S.insert(*m);
	Atom* a1 = new Atom();
	Atom* a2 = new Atom();
	m->insert(*a1);
	m->insert(*a2);

	a1->setName("A1");
	a1->setElement(PTE[Element::N]);
	a1->setCharge(0.5);
	a1->setPosition(Vector3(0.1, 0.2, 0.3));

	a2->setName("A2");
	a2->setElement(PTE[Element::O]);
	a2->setCharge(-0.5);
	a2->setPosition(Vector3(0.5, 0.6, 0.7));

	a1->createBond(*a2);
	a1->getBond(*a2)->setOrder(Bond::ORDER__DOUBLE);

	String filename;
	NEW_TMP_FILE(filename)
	MOL2File f(filename, std::ios::out);
	f << S;
	f.close();

	TEST_FILE_REGEXP(filename.c_str(), "data/MOL2File_test.mol2")
RESULT

CHECK(Reading of triple bonds)
	MOL2File f("data/MOL2File_test2.mol2");
	System S;
	CAPTURE_OUTPUT_LEVEL(2000)
	f >> S;
	COMPARE_OUTPUT("")
	f.close();
	TEST_EQUAL(S.countAtoms(), 21)
	TEST_EQUAL(S.countResidues(), 0)
	Size number_of_bonds = 0;
	Atom::BondIterator bond_it;
	AtomIterator atom_it;
	BALL_FOREACH_BOND(S, atom_it, bond_it)
	{
		number_of_bonds++;
	}
	TEST_EQUAL(number_of_bonds, 23)
RESULT
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<|endoftext|>