<commit_before>// Scintilla source code edit control
/** @file LexYAML.cxx
 ** Lexer for YAML.
 **/
// Copyright 2003- by Sean O'Dell <sean@celsoft.com>
// Release under the same license as Scintilla/SciTE.

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

#include "Platform.h"

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

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static const char * const yamlWordListDesc[] = {
	"Keywords",
	0
};

static inline bool AtEOL(Accessor &styler, unsigned int i) {
	return (styler[i] == '\n') ||
		((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
}

static unsigned int SpaceCount(char* lineBuffer) {
	if (lineBuffer == NULL)
		return 0;

	char* headBuffer = lineBuffer;

	while (*headBuffer == ' ')
		headBuffer++;

	return headBuffer - lineBuffer;
}

#define YAML_STATE_BITSIZE 16
#define YAML_STATE_MASK			(0xFFFF0000)
#define YAML_STATE_DOCUMENT		(1 << YAML_STATE_BITSIZE)
#define YAML_STATE_VALUE			(2 << YAML_STATE_BITSIZE)
#define YAML_STATE_COMMENT		(3 << YAML_STATE_BITSIZE)
#define YAML_STATE_TEXT_PARENT	(4 << YAML_STATE_BITSIZE)
#define YAML_STATE_TEXT			(5 << YAML_STATE_BITSIZE)

static void ColouriseYAMLLine(
	char *lineBuffer,
	unsigned int currentLine,
	unsigned int lengthLine,
	unsigned int startLine,
	unsigned int endPos,
	WordList &keywords,
	Accessor &styler) {

	unsigned int i = 0;
	bool bInQuotes = false;
	unsigned int indentAmount = SpaceCount(lineBuffer);

	if (currentLine > 0) {
		int parentLineState = styler.GetLineState(currentLine - 1);

		if ((parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT || (parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT_PARENT) {
			unsigned int parentIndentAmount = parentLineState&(~YAML_STATE_MASK);
			if (indentAmount > parentIndentAmount) {
				styler.SetLineState(currentLine, YAML_STATE_TEXT | parentIndentAmount);
				styler.ColourTo(endPos, SCE_YAML_TEXT);
				return;
			}
		}
	}
	styler.SetLineState(currentLine, 0);
	if (strncmp(lineBuffer, "---", 3) == 0) {	// Document marker
		styler.SetLineState(currentLine, YAML_STATE_DOCUMENT);
		styler.ColourTo(endPos, SCE_YAML_DOCUMENT);
		return;
	}
	// Skip initial spaces
	while ((i < lengthLine) && lineBuffer[i] == ' ') { // YAML always uses space, never TABS or anything else
		i++;
	}
	if (lineBuffer[i] == '\t') { // if we skipped all spaces, and we are NOT inside a text block, this is wrong
		styler.ColourTo(endPos, SCE_YAML_ERROR);
		return;
	}
	if (lineBuffer[i] == '#') {	// Comment
		styler.SetLineState(currentLine, YAML_STATE_COMMENT);
		styler.ColourTo(endPos, SCE_YAML_COMMENT);
		return;
	}
	while (i < lengthLine) {
		if (lineBuffer[i] == '\'' || lineBuffer[i] == '\"') {
			bInQuotes = !bInQuotes;
		} else if (lineBuffer[i] == ':' && !bInQuotes) {
			styler.ColourTo(startLine + i - 1, SCE_YAML_IDENTIFIER);
			styler.ColourTo(startLine + i, SCE_YAML_OPERATOR);
			// Non-folding scalar
			i++;
			while ((i < lengthLine) && isspacechar(lineBuffer[i]))
				i++;
			unsigned int endValue = lengthLine - 1;
			while ((endValue >= i) && isspacechar(lineBuffer[endValue]))
				endValue--;
			lineBuffer[endValue + 1] = '\0';
			if (lineBuffer[i] == '|' || lineBuffer[i] == '>') {
				i++;
				if (lineBuffer[i] == '+' || lineBuffer[i] == '-')
					i++;
				while ((i < lengthLine) && isspacechar(lineBuffer[i]))
					i++;
				if (lineBuffer[i] == '\0') {
					styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount);
					styler.ColourTo(endPos, SCE_YAML_DEFAULT);
					return;
				} else if (lineBuffer[i] == '#') {
					styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount);
					styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT);
					styler.ColourTo(endPos, SCE_YAML_COMMENT);
					return;
				} else {
					styler.ColourTo(endPos, SCE_YAML_ERROR);
					return;
				}
			} else if (lineBuffer[i] == '#') {
				styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT);
				styler.ColourTo(endPos, SCE_YAML_COMMENT);
				return;
			}
			styler.SetLineState(currentLine, YAML_STATE_VALUE);
			if (lineBuffer[i] == '&' || lineBuffer[i] == '*') {
				styler.ColourTo(endPos, SCE_YAML_REFERENCE);
				return;
			}
			if (keywords.InList(&lineBuffer[i])) { // Convertible value (true/false, etc.)
				styler.ColourTo(endPos, SCE_YAML_KEYWORD);
				return;
			} else {
				unsigned int i2 = i;
				while ((i < lengthLine) && lineBuffer[i]) {
					if (!(isascii(lineBuffer[i]) && isdigit(lineBuffer[i])) && lineBuffer[i] != '-' && lineBuffer[i] != '.' && lineBuffer[i] != ',') {
						styler.ColourTo(endPos, SCE_YAML_DEFAULT);
						return;
					}
					i++;
				}
				if (i > i2) {
					styler.ColourTo(endPos, SCE_YAML_NUMBER);
					return;
				}
			}
			break; // shouldn't get here, but just in case, the rest of the line is coloured the default
		}
		i++;
	}
	styler.ColourTo(endPos, SCE_YAML_DEFAULT);
}

static void ColouriseYAMLDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {
	char lineBuffer[1024];
	styler.StartAt(startPos);
	styler.StartSegment(startPos);
	unsigned int linePos = 0;
	unsigned int startLine = startPos;
	unsigned int endPos = startPos + length;
	unsigned int maxPos = styler.Length();
	unsigned int lineCurrent = styler.GetLine(startPos);

	for (unsigned int i = startPos; i < maxPos && i < endPos; i++) {
		lineBuffer[linePos++] = styler[i];
		if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
			// End of line (or of line buffer) met, colourise it
			lineBuffer[linePos] = '\0';
			ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, i, *keywordLists[0], styler);
			linePos = 0;
			startLine = i + 1;
			lineCurrent++;
		}
	}
	if (linePos > 0) {	// Last line does not have ending characters
		ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, startPos + length - 1, *keywordLists[0], styler);
	}
}

static bool IsCommentLine(int line, Accessor &styler) {
	int pos = styler.LineStart(line);
	if (styler[pos] == '#')
		return true;
	return false;
}

static void FoldYAMLDoc(unsigned int startPos, int length, int /*initStyle - unused*/,
                      WordList *[], Accessor &styler) {
	const int maxPos = startPos + length;
	const int maxLines = styler.GetLine(maxPos - 1);             // Requested last line
	const int docLines = styler.GetLine(styler.Length() - 1);  // Available last line
	const bool foldComment = styler.GetPropertyInt("fold.comment.yaml") != 0;

	// Backtrack to previous non-blank line so we can determine indent level
	// for any white space lines
	// and so we can fix any preceding fold level (which is why we go back
	// at least one line in all cases)
	int spaceFlags = 0;
	int lineCurrent = styler.GetLine(startPos);
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
	while (lineCurrent > 0) {
		lineCurrent--;
		indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
		if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&
		        (!IsCommentLine(lineCurrent, styler)))
			break;
	}
	int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;

	// Set up initial loop state
	int prevComment = 0;
	if (lineCurrent >= 1)
		prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);

	// Process all characters to end of requested range
	// or comment that hangs over the end of the range.  Cap processing in all cases
	// to end of document (in case of unclosed comment at end).
	while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) {

		// Gather info
		int lev = indentCurrent;
		int lineNext = lineCurrent + 1;
		int indentNext = indentCurrent;
		if (lineNext <= docLines) {
			// Information about next line is only available if not at end of document
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
	}
		const int comment = foldComment && IsCommentLine(lineCurrent, styler);
		const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
		                           IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));
		const int comment_continue = (comment && prevComment);
		if (!comment)
			indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
		if (indentNext & SC_FOLDLEVELWHITEFLAG)
			indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;

		if (comment_start) {
			// Place fold point at start of a block of comments
			lev |= SC_FOLDLEVELHEADERFLAG;
		} else if (comment_continue) {
			// Add level to rest of lines in the block
			lev = lev + 1;
		}

		// Skip past any blank lines for next indent level info; we skip also
		// comments (all comments, not just those starting in column 0)
		// which effectively folds them into surrounding code rather
		// than screwing up folding.

		while ((lineNext < docLines) &&
		        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
		         (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {

			lineNext++;
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
		}

		const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
		const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);

		// Now set all the indent levels on the lines we skipped
		// Do this from end to start.  Once we encounter one line
		// which is indented more than the line after the end of
		// the comment-block, use the level of the block before

		int skipLine = lineNext;
		int skipLevel = levelAfterComments;

		while (--skipLine > lineCurrent) {
			int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);

			if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
				skipLevel = levelBeforeComments;

			int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;

			styler.SetLevel(skipLine, skipLevel | whiteFlag);
		}

		// Set fold header on non-comment line
		if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
			if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
				lev |= SC_FOLDLEVELHEADERFLAG;
		}

		// Keep track of block comment state of previous line
		prevComment = comment_start || comment_continue;

		// Set fold level for this line and move to next line
		styler.SetLevel(lineCurrent, lev);
		indentCurrent = indentNext;
		lineCurrent = lineNext;
	}

	// NOTE: Cannot set level of last line here because indentCurrent doesn't have
	// header flag set; the loop above is crafted to take care of this case!
	//styler.SetLevel(lineCurrent, indentCurrent);
}

LexerModule lmYAML(SCLEX_YAML, ColouriseYAMLDoc, "yaml", FoldYAMLDoc, yamlWordListDesc);
<commit_msg>Update from Sean O'Dell changes the license text to be the same as other code.<commit_after>// Scintilla source code edit control
/** @file LexYAML.cxx
 ** Lexer for YAML.
 **/
// Copyright 2003- by Sean O'Dell <sean@celsoft.com>
// The License.txt file describes the conditions under which this software may be distributed.

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

#include "Platform.h"

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

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static const char * const yamlWordListDesc[] = {
	"Keywords",
	0
};

static inline bool AtEOL(Accessor &styler, unsigned int i) {
	return (styler[i] == '\n') ||
		((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
}

static unsigned int SpaceCount(char* lineBuffer) {
	if (lineBuffer == NULL)
		return 0;

	char* headBuffer = lineBuffer;

	while (*headBuffer == ' ')
		headBuffer++;

	return headBuffer - lineBuffer;
}

#define YAML_STATE_BITSIZE 16
#define YAML_STATE_MASK			(0xFFFF0000)
#define YAML_STATE_DOCUMENT		(1 << YAML_STATE_BITSIZE)
#define YAML_STATE_VALUE			(2 << YAML_STATE_BITSIZE)
#define YAML_STATE_COMMENT		(3 << YAML_STATE_BITSIZE)
#define YAML_STATE_TEXT_PARENT	(4 << YAML_STATE_BITSIZE)
#define YAML_STATE_TEXT			(5 << YAML_STATE_BITSIZE)

static void ColouriseYAMLLine(
	char *lineBuffer,
	unsigned int currentLine,
	unsigned int lengthLine,
	unsigned int startLine,
	unsigned int endPos,
	WordList &keywords,
	Accessor &styler) {

	unsigned int i = 0;
	bool bInQuotes = false;
	unsigned int indentAmount = SpaceCount(lineBuffer);

	if (currentLine > 0) {
		int parentLineState = styler.GetLineState(currentLine - 1);

		if ((parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT || (parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT_PARENT) {
			unsigned int parentIndentAmount = parentLineState&(~YAML_STATE_MASK);
			if (indentAmount > parentIndentAmount) {
				styler.SetLineState(currentLine, YAML_STATE_TEXT | parentIndentAmount);
				styler.ColourTo(endPos, SCE_YAML_TEXT);
				return;
			}
		}
	}
	styler.SetLineState(currentLine, 0);
	if (strncmp(lineBuffer, "---", 3) == 0) {	// Document marker
		styler.SetLineState(currentLine, YAML_STATE_DOCUMENT);
		styler.ColourTo(endPos, SCE_YAML_DOCUMENT);
		return;
	}
	// Skip initial spaces
	while ((i < lengthLine) && lineBuffer[i] == ' ') { // YAML always uses space, never TABS or anything else
		i++;
	}
	if (lineBuffer[i] == '\t') { // if we skipped all spaces, and we are NOT inside a text block, this is wrong
		styler.ColourTo(endPos, SCE_YAML_ERROR);
		return;
	}
	if (lineBuffer[i] == '#') {	// Comment
		styler.SetLineState(currentLine, YAML_STATE_COMMENT);
		styler.ColourTo(endPos, SCE_YAML_COMMENT);
		return;
	}
	while (i < lengthLine) {
		if (lineBuffer[i] == '\'' || lineBuffer[i] == '\"') {
			bInQuotes = !bInQuotes;
		} else if (lineBuffer[i] == ':' && !bInQuotes) {
			styler.ColourTo(startLine + i - 1, SCE_YAML_IDENTIFIER);
			styler.ColourTo(startLine + i, SCE_YAML_OPERATOR);
			// Non-folding scalar
			i++;
			while ((i < lengthLine) && isspacechar(lineBuffer[i]))
				i++;
			unsigned int endValue = lengthLine - 1;
			while ((endValue >= i) && isspacechar(lineBuffer[endValue]))
				endValue--;
			lineBuffer[endValue + 1] = '\0';
			if (lineBuffer[i] == '|' || lineBuffer[i] == '>') {
				i++;
				if (lineBuffer[i] == '+' || lineBuffer[i] == '-')
					i++;
				while ((i < lengthLine) && isspacechar(lineBuffer[i]))
					i++;
				if (lineBuffer[i] == '\0') {
					styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount);
					styler.ColourTo(endPos, SCE_YAML_DEFAULT);
					return;
				} else if (lineBuffer[i] == '#') {
					styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount);
					styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT);
					styler.ColourTo(endPos, SCE_YAML_COMMENT);
					return;
				} else {
					styler.ColourTo(endPos, SCE_YAML_ERROR);
					return;
				}
			} else if (lineBuffer[i] == '#') {
				styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT);
				styler.ColourTo(endPos, SCE_YAML_COMMENT);
				return;
			}
			styler.SetLineState(currentLine, YAML_STATE_VALUE);
			if (lineBuffer[i] == '&' || lineBuffer[i] == '*') {
				styler.ColourTo(endPos, SCE_YAML_REFERENCE);
				return;
			}
			if (keywords.InList(&lineBuffer[i])) { // Convertible value (true/false, etc.)
				styler.ColourTo(endPos, SCE_YAML_KEYWORD);
				return;
			} else {
				unsigned int i2 = i;
				while ((i < lengthLine) && lineBuffer[i]) {
					if (!(isascii(lineBuffer[i]) && isdigit(lineBuffer[i])) && lineBuffer[i] != '-' && lineBuffer[i] != '.' && lineBuffer[i] != ',') {
						styler.ColourTo(endPos, SCE_YAML_DEFAULT);
						return;
					}
					i++;
				}
				if (i > i2) {
					styler.ColourTo(endPos, SCE_YAML_NUMBER);
					return;
				}
			}
			break; // shouldn't get here, but just in case, the rest of the line is coloured the default
		}
		i++;
	}
	styler.ColourTo(endPos, SCE_YAML_DEFAULT);
}

static void ColouriseYAMLDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {
	char lineBuffer[1024];
	styler.StartAt(startPos);
	styler.StartSegment(startPos);
	unsigned int linePos = 0;
	unsigned int startLine = startPos;
	unsigned int endPos = startPos + length;
	unsigned int maxPos = styler.Length();
	unsigned int lineCurrent = styler.GetLine(startPos);

	for (unsigned int i = startPos; i < maxPos && i < endPos; i++) {
		lineBuffer[linePos++] = styler[i];
		if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
			// End of line (or of line buffer) met, colourise it
			lineBuffer[linePos] = '\0';
			ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, i, *keywordLists[0], styler);
			linePos = 0;
			startLine = i + 1;
			lineCurrent++;
		}
	}
	if (linePos > 0) {	// Last line does not have ending characters
		ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, startPos + length - 1, *keywordLists[0], styler);
	}
}

static bool IsCommentLine(int line, Accessor &styler) {
	int pos = styler.LineStart(line);
	if (styler[pos] == '#')
		return true;
	return false;
}

static void FoldYAMLDoc(unsigned int startPos, int length, int /*initStyle - unused*/,
                      WordList *[], Accessor &styler) {
	const int maxPos = startPos + length;
	const int maxLines = styler.GetLine(maxPos - 1);             // Requested last line
	const int docLines = styler.GetLine(styler.Length() - 1);  // Available last line
	const bool foldComment = styler.GetPropertyInt("fold.comment.yaml") != 0;

	// Backtrack to previous non-blank line so we can determine indent level
	// for any white space lines
	// and so we can fix any preceding fold level (which is why we go back
	// at least one line in all cases)
	int spaceFlags = 0;
	int lineCurrent = styler.GetLine(startPos);
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
	while (lineCurrent > 0) {
		lineCurrent--;
		indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
		if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&
		        (!IsCommentLine(lineCurrent, styler)))
			break;
	}
	int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;

	// Set up initial loop state
	int prevComment = 0;
	if (lineCurrent >= 1)
		prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);

	// Process all characters to end of requested range
	// or comment that hangs over the end of the range.  Cap processing in all cases
	// to end of document (in case of unclosed comment at end).
	while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) {

		// Gather info
		int lev = indentCurrent;
		int lineNext = lineCurrent + 1;
		int indentNext = indentCurrent;
		if (lineNext <= docLines) {
			// Information about next line is only available if not at end of document
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
	}
		const int comment = foldComment && IsCommentLine(lineCurrent, styler);
		const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
		                           IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));
		const int comment_continue = (comment && prevComment);
		if (!comment)
			indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
		if (indentNext & SC_FOLDLEVELWHITEFLAG)
			indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;

		if (comment_start) {
			// Place fold point at start of a block of comments
			lev |= SC_FOLDLEVELHEADERFLAG;
		} else if (comment_continue) {
			// Add level to rest of lines in the block
			lev = lev + 1;
		}

		// Skip past any blank lines for next indent level info; we skip also
		// comments (all comments, not just those starting in column 0)
		// which effectively folds them into surrounding code rather
		// than screwing up folding.

		while ((lineNext < docLines) &&
		        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
		         (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {

			lineNext++;
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
		}

		const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
		const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);

		// Now set all the indent levels on the lines we skipped
		// Do this from end to start.  Once we encounter one line
		// which is indented more than the line after the end of
		// the comment-block, use the level of the block before

		int skipLine = lineNext;
		int skipLevel = levelAfterComments;

		while (--skipLine > lineCurrent) {
			int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);

			if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
				skipLevel = levelBeforeComments;

			int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;

			styler.SetLevel(skipLine, skipLevel | whiteFlag);
		}

		// Set fold header on non-comment line
		if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
			if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
				lev |= SC_FOLDLEVELHEADERFLAG;
		}

		// Keep track of block comment state of previous line
		prevComment = comment_start || comment_continue;

		// Set fold level for this line and move to next line
		styler.SetLevel(lineCurrent, lev);
		indentCurrent = indentNext;
		lineCurrent = lineNext;
	}

	// NOTE: Cannot set level of last line here because indentCurrent doesn't have
	// header flag set; the loop above is crafted to take care of this case!
	//styler.SetLevel(lineCurrent, indentCurrent);
}

LexerModule lmYAML(SCLEX_YAML, ColouriseYAMLDoc, "yaml", FoldYAMLDoc, yamlWordListDesc);
<|endoftext|>


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

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

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

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

=========================================================================*/
#include "LinExtrd.hh"

// Description:
// Create object with normal extrusion type, capping on, scale factor=1.0,
// vector (0,0,1), and point (0,0,0).
vlLinearExtrusionFilter::vlLinearExtrusionFilter()
{
  this->ExtrusionType = NORMAL_EXTRUSION;
  this->Capping = 1;
  this->ScaleFactor = 1.0;
  this->Vector[0] = this->Vector[1] = 0.0; this->Vector[2] = 1.0;
  this->Point[0] = this->Point[1] = this->Point[2] = 0.0;
}

float *vlLinearExtrusionFilter::ViaNormal(float x[3], int id, vlNormals *n)
{
  static float xNew[3], *normal;
  int i;

  normal = n->GetNormal(id);
  for (i=0; i<3; i++)
    xNew[i] = x[i] + this->ScaleFactor*normal[i];

  return xNew;
}

float *vlLinearExtrusionFilter::ViaVector(float x[3], int id, vlNormals *n)
{
  static float xNew[3];
  int i;

  for (i=0; i<3; i++)
    xNew[i] = x[i] + this->ScaleFactor*this->Vector[i];

  return xNew;
}

float *vlLinearExtrusionFilter::ViaPoint(float x[3], int id, vlNormals *n)
{
  static float xNew[3];
  int i;

  for (i=0; i<3; i++)
    xNew[i] = x[i] + this->ScaleFactor*(x[i] - this->Point[i]);

  return xNew;
}

void vlLinearExtrusionFilter::Execute()
{
  int numPts, numCells;
  vlPolyData *input=(vlPolyData *)this->Input;
  vlPointData *pd=input->GetPointData();
  vlNormals *inNormals;
  vlPolyData mesh;
  vlPoints *inPts;
  vlCellArray *inVerts, *inLines, *inPolys, *inStrips;
  int npts, *pts, numEdges, cellId, dim;
  int ptId, ncells, ptIds[MAX_CELL_SIZE], i, j, k, p1, p2;
  float *x;
  vlFloatPoints *newPts;
  vlCellArray *newLines=NULL, *newPolys=NULL, *newStrips=NULL;
  vlCell *cell, *edge;
  vlIdList cellIds(MAX_CELL_SIZE), *cellPts;
//
// Initialize / check input
//
  vlDebugMacro(<<"Linearly extruding data");
  this->Initialize();

  if ( (numPts=input->GetNumberOfPoints()) < 1 ||
  (numCells=input->GetNumberOfCells()) < 1 )
    {
    vlErrorMacro(<<"No data to extrude!");
    return;
    }
//
// Decide which vector to use for extrusion
//
  if ( this->ExtrusionType == POINT_EXTRUSION )
    {
    this->ExtrudePoint = &vlLinearExtrusionFilter::ViaPoint;
    }
  else if ( this->ExtrusionType == NORMAL_EXTRUSION  &&
  (inNormals = pd->GetNormals()) != NULL )
    {
    this->ExtrudePoint = &vlLinearExtrusionFilter::ViaNormal;
    inNormals = pd->GetNormals();
    }
  else // Vector_EXTRUSION
    {
    this->ExtrudePoint = &vlLinearExtrusionFilter::ViaVector;
    }
//
// Build cell data structure.
//
  inPts = input->GetPoints();
  inVerts = input->GetVerts();
  inLines = input->GetLines();
  inPolys = input->GetPolys();
  inStrips = input->GetStrips();
  mesh.SetPoints(inPts);
  mesh.SetVerts(inVerts);
  mesh.SetLines(inLines);
  mesh.SetPolys(inPolys);
  mesh.SetStrips(inStrips);
  if ( inPolys || inStrips ) mesh.BuildLinks();
//
// Allocate memory for output. We don't copy normals because surface geometry
// is modified. Copy all points - this is the usual requirement and it makes
// creation of skirt much easier.
//
  this->PointData.CopyNormalsOff();
  this->PointData.CopyAllocate(pd,2*numPts);
  newPts = new vlFloatPoints(2*numPts);
  if ( (ncells=inVerts->GetNumberOfCells()) > 0 )
    {
    newLines = new vlCellArray;
    newLines->Allocate(newLines->EstimateSize(ncells,2));
    }
  // arbitrary initial allocation size
  ncells = inLines->GetNumberOfCells() + inPolys->GetNumberOfCells()/10 +
           inStrips->GetNumberOfCells()/10;
  ncells = (ncells < 100 ? 100 : ncells);
  newStrips = new vlCellArray;
  newStrips->Allocate(newStrips->EstimateSize(ncells,4));

  // copy points
  for (ptId=0; ptId < numPts; ptId++)
    {
    x = inPts->GetPoint(ptId);
    newPts->SetPoint(ptId,x);
    newPts->SetPoint(ptId+numPts,(this->*(ExtrudePoint))(x,ptId,inNormals));
    this->PointData.CopyData(pd,ptId,ptId);
    this->PointData.CopyData(pd,ptId,ptId+numPts);
    }
//
// If capping is on, copy 2D cells to output (plus create cap)
//
  if ( this->Capping )
    {
    if ( inPolys->GetNumberOfCells() > 0 )
      {
      newPolys = new vlCellArray(inPolys->GetSize());
      for ( inPolys->InitTraversal(); inPolys->GetNextCell(npts,pts); )
        {
        newPolys->InsertNextCell(npts,pts);
        newPolys->InsertNextCell(npts);
        for (i=0; i < npts; i++)
          newPolys->InsertCellPoint(pts[i] + numPts);
        }
      }

    if ( inStrips->GetNumberOfCells() > 0 )
      {
      for ( inStrips->InitTraversal(); inStrips->GetNextCell(npts,pts); )
        {
        newStrips->InsertNextCell(npts,pts);
        newStrips->InsertNextCell(npts);
        for (i=0; i < npts; i++)
          newStrips->InsertCellPoint(pts[i] + numPts);
        }
      }
    }
//
// Loop over all polygons and triangle strips searching for boundary edges.
// If boundary edge found, extrude triangle strip.
//
  for ( cellId=0; cellId < numCells; cellId++)
    {
    cell = mesh.GetCell(cellId);
    cellPts = cell->GetPointIds();

    if ( (dim=cell->GetCellDimension()) == 0 ) //create lines from points
      {
      for (i=0; i<cellPts->GetNumberOfIds(); i++)
        {
        newLines->InsertNextCell(2);
        ptId = cellPts->GetId(i);
        newLines->InsertCellPoint(ptId);
        newLines->InsertCellPoint(ptId+numPts);
        }
      }

    else if ( dim == 1 ) // create strips from lines
      {
      for (i=0; i < (cellPts->GetNumberOfIds()-1); i++)
        {
        p1 = cellPts->GetId(i);
        p2 = cellPts->GetId(i+1);
        newStrips->InsertNextCell(4);
        newStrips->InsertCellPoint(p1);
        newStrips->InsertCellPoint(p2);
        newStrips->InsertCellPoint(p1+numPts);
        newStrips->InsertCellPoint(p2+numPts);
        }
      }

    else if ( dim == 2 ) // create strips from boundary edges
      {
      numEdges = cell->GetNumberOfEdges();
      for (i=0; i<numEdges; i++)
        {
        edge = cell->GetEdge(i);
        for (j=0; j<(edge->GetNumberOfPoints()-1); j++)
          {
          p1 = edge->PointIds.GetId(j);
          p2 = edge->PointIds.GetId(j+1);
          mesh.GetCellEdgeNeighbors(cellId, p1, p2, cellIds);

          if ( cellIds.GetNumberOfIds() < 1 ) //generate strip
            {
            newStrips->InsertNextCell(4);
            newStrips->InsertCellPoint(p1);
            newStrips->InsertCellPoint(p2);
            newStrips->InsertCellPoint(p1+numPts);
            newStrips->InsertCellPoint(p2+numPts);
            }
          } //for each sub-edge
        } //for each edge
      } //for each polygon or triangle strip
    } //for each cell
//
// Send data to output
//
  this->SetPoints(newPts);
  if ( newLines ) this->SetLines(newLines);
  if ( newPolys ) this->SetPolys(newLines);
  this->SetStrips(newStrips);

  this->Squeeze();
}

void vlLinearExtrusionFilter::PrintSelf(ostream& os, vlIndent indent)
{
  vlPolyToPolyFilter::PrintSelf(os,indent);

  if ( this->ExtrusionType == VECTOR_EXTRUSION )
    {
    os << indent << "Extrusion Type: Extrude along vector\n";
    os << indent << "Vector: (" << this->Vector[0] << ", "
       << this->Vector[1] << ", " << this->Vector[2] << ")\n";
    }
  else if ( this->ExtrusionType == NORMAL_EXTRUSION )
    {
    os << indent << "Extrusion Type: Extrude along vertex normals\n";
    }
  else //POINT_EXTRUSION
    {
    os << indent << "Extrusion Type: Extrude towards point\n";
    os << indent << "Point: (" << this->Point[0] << ", "
       << this->Point[1] << ", " << this->Point[2] << ")\n";
    }

  os << indent << "Capping: " << (this->Capping ? "On\n" : "Off\n");
  os << indent << "Scale Factor: " << this->ScaleFactor << "\n";
}

<commit_msg>ERR: Fixed bug.<commit_after>/*=========================================================================

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

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

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

=========================================================================*/
#include "LinExtrd.hh"

// Description:
// Create object with normal extrusion type, capping on, scale factor=1.0,
// vector (0,0,1), and point (0,0,0).
vlLinearExtrusionFilter::vlLinearExtrusionFilter()
{
  this->ExtrusionType = NORMAL_EXTRUSION;
  this->Capping = 1;
  this->ScaleFactor = 1.0;
  this->Vector[0] = this->Vector[1] = 0.0; this->Vector[2] = 1.0;
  this->Point[0] = this->Point[1] = this->Point[2] = 0.0;
}

float *vlLinearExtrusionFilter::ViaNormal(float x[3], int id, vlNormals *n)
{
  static float xNew[3], *normal;
  int i;

  normal = n->GetNormal(id);
  for (i=0; i<3; i++)
    xNew[i] = x[i] + this->ScaleFactor*normal[i];

  return xNew;
}

float *vlLinearExtrusionFilter::ViaVector(float x[3], int id, vlNormals *n)
{
  static float xNew[3];
  int i;

  for (i=0; i<3; i++)
    xNew[i] = x[i] + this->ScaleFactor*this->Vector[i];

  return xNew;
}

float *vlLinearExtrusionFilter::ViaPoint(float x[3], int id, vlNormals *n)
{
  static float xNew[3];
  int i;

  for (i=0; i<3; i++)
    xNew[i] = x[i] + this->ScaleFactor*(x[i] - this->Point[i]);

  return xNew;
}

void vlLinearExtrusionFilter::Execute()
{
  int numPts, numCells;
  vlPolyData *input=(vlPolyData *)this->Input;
  vlPointData *pd=input->GetPointData();
  vlNormals *inNormals;
  vlPolyData mesh;
  vlPoints *inPts;
  vlCellArray *inVerts, *inLines, *inPolys, *inStrips;
  int npts, *pts, numEdges, cellId, dim;
  int ptId, ncells, ptIds[MAX_CELL_SIZE], i, j, k, p1, p2;
  float *x;
  vlFloatPoints *newPts;
  vlCellArray *newLines=NULL, *newPolys=NULL, *newStrips=NULL;
  vlCell *cell, *edge;
  vlIdList cellIds(MAX_CELL_SIZE), *cellPts;
//
// Initialize / check input
//
  vlDebugMacro(<<"Linearly extruding data");
  this->Initialize();

  if ( (numPts=input->GetNumberOfPoints()) < 1 ||
  (numCells=input->GetNumberOfCells()) < 1 )
    {
    vlErrorMacro(<<"No data to extrude!");
    return;
    }
//
// Decide which vector to use for extrusion
//
  if ( this->ExtrusionType == POINT_EXTRUSION )
    {
    this->ExtrudePoint = &vlLinearExtrusionFilter::ViaPoint;
    }
  else if ( this->ExtrusionType == NORMAL_EXTRUSION  &&
  (inNormals = pd->GetNormals()) != NULL )
    {
    this->ExtrudePoint = &vlLinearExtrusionFilter::ViaNormal;
    inNormals = pd->GetNormals();
    }
  else // Vector_EXTRUSION
    {
    this->ExtrudePoint = &vlLinearExtrusionFilter::ViaVector;
    }
//
// Build cell data structure.
//
  inPts = input->GetPoints();
  inVerts = input->GetVerts();
  inLines = input->GetLines();
  inPolys = input->GetPolys();
  inStrips = input->GetStrips();
  mesh.SetPoints(inPts);
  mesh.SetVerts(inVerts);
  mesh.SetLines(inLines);
  mesh.SetPolys(inPolys);
  mesh.SetStrips(inStrips);
  if ( inPolys || inStrips ) mesh.BuildLinks();
//
// Allocate memory for output. We don't copy normals because surface geometry
// is modified. Copy all points - this is the usual requirement and it makes
// creation of skirt much easier.
//
  this->PointData.CopyNormalsOff();
  this->PointData.CopyAllocate(pd,2*numPts);
  newPts = new vlFloatPoints(2*numPts);
  if ( (ncells=inVerts->GetNumberOfCells()) > 0 )
    {
    newLines = new vlCellArray;
    newLines->Allocate(newLines->EstimateSize(ncells,2));
    }
  // arbitrary initial allocation size
  ncells = inLines->GetNumberOfCells() + inPolys->GetNumberOfCells()/10 +
           inStrips->GetNumberOfCells()/10;
  ncells = (ncells < 100 ? 100 : ncells);
  newStrips = new vlCellArray;
  newStrips->Allocate(newStrips->EstimateSize(ncells,4));

  // copy points
  for (ptId=0; ptId < numPts; ptId++)
    {
    x = inPts->GetPoint(ptId);
    newPts->SetPoint(ptId,x);
    newPts->SetPoint(ptId+numPts,(this->*(ExtrudePoint))(x,ptId,inNormals));
    this->PointData.CopyData(pd,ptId,ptId);
    this->PointData.CopyData(pd,ptId,ptId+numPts);
    }
//
// If capping is on, copy 2D cells to output (plus create cap)
//
  if ( this->Capping )
    {
    if ( inPolys->GetNumberOfCells() > 0 )
      {
      newPolys = new vlCellArray(inPolys->GetSize());
      for ( inPolys->InitTraversal(); inPolys->GetNextCell(npts,pts); )
        {
        newPolys->InsertNextCell(npts,pts);
        newPolys->InsertNextCell(npts);
        for (i=0; i < npts; i++)
          newPolys->InsertCellPoint(pts[i] + numPts);
        }
      }

    if ( inStrips->GetNumberOfCells() > 0 )
      {
      for ( inStrips->InitTraversal(); inStrips->GetNextCell(npts,pts); )
        {
        newStrips->InsertNextCell(npts,pts);
        newStrips->InsertNextCell(npts);
        for (i=0; i < npts; i++)
          newStrips->InsertCellPoint(pts[i] + numPts);
        }
      }
    }
//
// Loop over all polygons and triangle strips searching for boundary edges.
// If boundary edge found, extrude triangle strip.
//
  for ( cellId=0; cellId < numCells; cellId++)
    {
    cell = mesh.GetCell(cellId);
    cellPts = cell->GetPointIds();

    if ( (dim=cell->GetCellDimension()) == 0 ) //create lines from points
      {
      for (i=0; i<cellPts->GetNumberOfIds(); i++)
        {
        newLines->InsertNextCell(2);
        ptId = cellPts->GetId(i);
        newLines->InsertCellPoint(ptId);
        newLines->InsertCellPoint(ptId+numPts);
        }
      }

    else if ( dim == 1 ) // create strips from lines
      {
      for (i=0; i < (cellPts->GetNumberOfIds()-1); i++)
        {
        p1 = cellPts->GetId(i);
        p2 = cellPts->GetId(i+1);
        newStrips->InsertNextCell(4);
        newStrips->InsertCellPoint(p1);
        newStrips->InsertCellPoint(p2);
        newStrips->InsertCellPoint(p1+numPts);
        newStrips->InsertCellPoint(p2+numPts);
        }
      }

    else if ( dim == 2 ) // create strips from boundary edges
      {
      numEdges = cell->GetNumberOfEdges();
      for (i=0; i<numEdges; i++)
        {
        edge = cell->GetEdge(i);
        for (j=0; j<(edge->GetNumberOfPoints()-1); j++)
          {
          p1 = edge->PointIds.GetId(j);
          p2 = edge->PointIds.GetId(j+1);
          mesh.GetCellEdgeNeighbors(cellId, p1, p2, cellIds);

          if ( cellIds.GetNumberOfIds() < 1 ) //generate strip
            {
            newStrips->InsertNextCell(4);
            newStrips->InsertCellPoint(p1);
            newStrips->InsertCellPoint(p2);
            newStrips->InsertCellPoint(p1+numPts);
            newStrips->InsertCellPoint(p2+numPts);
            }
          } //for each sub-edge
        } //for each edge
      } //for each polygon or triangle strip
    } //for each cell
//
// Send data to output
//
  this->SetPoints(newPts);
  if ( newLines ) this->SetLines(newLines);
  if ( newPolys ) this->SetPolys(newPolys);
  this->SetStrips(newStrips);

  this->Squeeze();
}

void vlLinearExtrusionFilter::PrintSelf(ostream& os, vlIndent indent)
{
  vlPolyToPolyFilter::PrintSelf(os,indent);

  if ( this->ExtrusionType == VECTOR_EXTRUSION )
    {
    os << indent << "Extrusion Type: Extrude along vector\n";
    os << indent << "Vector: (" << this->Vector[0] << ", "
       << this->Vector[1] << ", " << this->Vector[2] << ")\n";
    }
  else if ( this->ExtrusionType == NORMAL_EXTRUSION )
    {
    os << indent << "Extrusion Type: Extrude along vertex normals\n";
    }
  else //POINT_EXTRUSION
    {
    os << indent << "Extrusion Type: Extrude towards point\n";
    os << indent << "Point: (" << this->Point[0] << ", "
       << this->Point[1] << ", " << this->Point[2] << ")\n";
    }

  os << indent << "Capping: " << (this->Capping ? "On\n" : "Off\n");
  os << indent << "Scale Factor: " << this->ScaleFactor << "\n";
}

<|endoftext|>


<commit_before>#include <iostream>
#include <cassert>
#include "ListCmd.h"
#include "VtkList.h"

using namespace std;

// ---------------------------------------------------------------------------

cigma::ListCmd::ListCmd()
{
    name = "list";
}

cigma::ListCmd::~ListCmd()
{
}

// ---------------------------------------------------------------------------

void cigma::ListCmd::setupOptions(AnyOption *opt)
{
    cout << "Calling cigma::ListCmd::setupOptions()" << endl;

    assert(opt != 0);

    /* setup usage */
    opt->addUsage("Usage:");
    opt->addUsage("   cigma list FILE");

    /* setup flags and options */
    opt->setFlag("help", 'h');

    return;
}

void cigma::ListCmd::configure(AnyOption *opt)
{
    cout << "Calling cigma::ListCmd::configure()" << endl;

    assert(opt != 0);
    char *in = 0;

    int argc = opt->getArgc();
    if (argc > 0)
    {
        in = opt->getArgv(0);
        filename = in;
    }

    return;
}

int cigma::ListCmd::run()
{
    cout << "Calling cigma::ListCmd::run()" << endl;

    if (filename == "")
    {
        return 1;
    }

    vtkls(filename.c_str());

    return 0;
}

// ---------------------------------------------------------------------------
<commit_msg>Reuse h5ls command, and disabled traces in ListCmd<commit_after>#include <iostream>
#include <cstdlib>
#include <cassert>
#include <string>
#include "ListCmd.h"
#include "VtkList.h"
#include "StringUtils.h"

using namespace std;

// ---------------------------------------------------------------------------

cigma::ListCmd::ListCmd()
{
    name = "list";
}

cigma::ListCmd::~ListCmd()
{
}

// ---------------------------------------------------------------------------

void cigma::ListCmd::setupOptions(AnyOption *opt)
{
    //cout << "Calling cigma::ListCmd::setupOptions()" << endl;

    assert(opt != 0);

    /* setup usage */
    opt->addUsage("Usage:");
    opt->addUsage("   cigma list FILE");

    /* setup flags and options */
    opt->setFlag("help", 'h');

    return;
}

void cigma::ListCmd::configure(AnyOption *opt)
{
    //cout << "Calling cigma::ListCmd::configure()" << endl;

    assert(opt != 0);
    char *in = 0;

    int argc = opt->getArgc();
    if (argc > 0)
    {
        in = opt->getArgv(0);
        filename = in;
    }

    return;
}

int cigma::ListCmd::run()
{
    //cout << "Calling cigma::ListCmd::run()" << endl;

    if (filename == "")
    {
        return 1;
    }

    string fileroot;
    string extension;

    path_splitext(filename, fileroot, extension);

    if (extension == ".vtk")
    {
        vtkls(filename.c_str());
    }
    else if (extension == ".h5")
    {
        int ret;
        string cmd = "h5ls -r ";
        cmd += filename;
        ret = system(cmd.c_str());
        return ret;
    }
    else
    {
        cerr << "list: File extension must be .h5 or .vtk" << endl;
        return 2;
    }

    return 0;
}

// ---------------------------------------------------------------------------
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "matchfeature.h"
#include "utils.h"
#include <vespa/searchlib/fef/fieldinfo.h>
#include <vespa/searchlib/fef/indexproperties.h>
#include <vespa/searchlib/fef/properties.h>
#include <vespa/vespalib/util/stash.h>

using namespace search::fef;
using CollectionType = FieldInfo::CollectionType;

namespace search::features {

MatchExecutor::MatchExecutor(const MatchParams & params) :
    FeatureExecutor(),
    _params(params)
{
}

void
MatchExecutor::execute(uint32_t)
{
    feature_t sum = 0.0f;
    feature_t totalWeight = 0.0f;
    for (uint32_t i = 0; i < _params.weights.size(); ++i) {
        feature_t weight = static_cast<feature_t>(_params.weights[i]);
        feature_t matchScore = inputs().get_number(i);
        if (matchScore > 0.0f) {
            totalWeight += weight;
            sum += (weight * matchScore);
        }
        outputs().set_number(i + 2, weight);
    }

    outputs().set_number(0, totalWeight > 0.0f ? sum / totalWeight : 0.0f);
    outputs().set_number(1, totalWeight);
}

MatchBlueprint::MatchBlueprint() :
    Blueprint("match"),
    _params()
{
}

MatchBlueprint::~MatchBlueprint() = default;

void
MatchBlueprint::visitDumpFeatures(const IIndexEnvironment & env,
                                  IDumpFeatureVisitor & visitor) const
{
    (void) env;
    (void) visitor;
}

Blueprint::UP
MatchBlueprint::createInstance() const
{
    return std::make_unique<MatchBlueprint>();
}

bool
MatchBlueprint::setup(const IIndexEnvironment & env,
                      const ParameterList &)
{
    for (uint32_t i = 0; i < env.getNumFields(); ++i) {
        const FieldInfo * info = env.getField(i);
        if ((info->type() == FieldType::INDEX) || (info->type() == FieldType::ATTRIBUTE)) {
            _params.weights.push_back(indexproperties::FieldWeight::lookup(env.getProperties(), info->name()));
            if (info->type() == FieldType::INDEX) {
                if (info->collection() == CollectionType::SINGLE) {
                    defineInput("fieldMatch(" + info->name() + ")");
                } else {
                    defineInput("elementCompleteness(" + info->name() + ")");
                }
            } else if (info->type() == FieldType::ATTRIBUTE) {
                defineInput("attributeMatch(" + info->name() + ")");
            }
        }
    }
    describeOutput("score", "Normalized sum over all matched fields");
    describeOutput("totalWeight", "Sum of rank weights for all matched fields");
    for (uint32_t i = 0; i < env.getNumFields(); ++i) {
        const FieldInfo * info = env.getField(i);
        if ((info->type() == FieldType::INDEX) || (info->type() == FieldType::ATTRIBUTE)) {
            describeOutput("weight." + info->name(), "The rank weight value for field '" + info->name() + "'");
        }
    }
    return true;
}

FeatureExecutor &
MatchBlueprint::createExecutor(const IQueryEnvironment &env, vespalib::Stash &stash) const
{
    (void) env;
    return stash.create<MatchExecutor>(_params);
}

}
<commit_msg>tensor-type fields are not matchable, skip in setup<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "matchfeature.h"
#include "utils.h"
#include <vespa/searchlib/fef/fieldinfo.h>
#include <vespa/searchlib/fef/indexproperties.h>
#include <vespa/searchlib/fef/properties.h>
#include <vespa/vespalib/util/stash.h>

using namespace search::fef;
using CollectionType = FieldInfo::CollectionType;

namespace search::features {

MatchExecutor::MatchExecutor(const MatchParams & params) :
    FeatureExecutor(),
    _params(params)
{
}

void
MatchExecutor::execute(uint32_t)
{
    feature_t sum = 0.0f;
    feature_t totalWeight = 0.0f;
    for (uint32_t i = 0; i < _params.weights.size(); ++i) {
        feature_t weight = static_cast<feature_t>(_params.weights[i]);
        feature_t matchScore = inputs().get_number(i);
        if (matchScore > 0.0f) {
            totalWeight += weight;
            sum += (weight * matchScore);
        }
        outputs().set_number(i + 2, weight);
    }

    outputs().set_number(0, totalWeight > 0.0f ? sum / totalWeight : 0.0f);
    outputs().set_number(1, totalWeight);
}

MatchBlueprint::MatchBlueprint() :
    Blueprint("match"),
    _params()
{
}

MatchBlueprint::~MatchBlueprint() = default;

void
MatchBlueprint::visitDumpFeatures(const IIndexEnvironment & env,
                                  IDumpFeatureVisitor & visitor) const
{
    (void) env;
    (void) visitor;
}

Blueprint::UP
MatchBlueprint::createInstance() const
{
    return std::make_unique<MatchBlueprint>();
}

bool
MatchBlueprint::setup(const IIndexEnvironment & env,
                      const ParameterList &)
{
    for (uint32_t i = 0; i < env.getNumFields(); ++i) {
        const FieldInfo * info = env.getField(i);
        if (info->get_data_type() == FieldInfo::DataType::TENSOR) {
            // not matchable
            continue;
        }
        if ((info->type() == FieldType::INDEX) || (info->type() == FieldType::ATTRIBUTE)) {
            _params.weights.push_back(indexproperties::FieldWeight::lookup(env.getProperties(), info->name()));
            if (info->type() == FieldType::INDEX) {
                if (info->collection() == CollectionType::SINGLE) {
                    defineInput("fieldMatch(" + info->name() + ")");
                } else {
                    defineInput("elementCompleteness(" + info->name() + ")");
                }
            } else if (info->type() == FieldType::ATTRIBUTE) {
                defineInput("attributeMatch(" + info->name() + ")");
            }
        }
    }
    describeOutput("score", "Normalized sum over all matched fields");
    describeOutput("totalWeight", "Sum of rank weights for all matched fields");
    for (uint32_t i = 0; i < env.getNumFields(); ++i) {
        const FieldInfo * info = env.getField(i);
        if ((info->type() == FieldType::INDEX) || (info->type() == FieldType::ATTRIBUTE)) {
            describeOutput("weight." + info->name(), "The rank weight value for field '" + info->name() + "'");
        }
    }
    return true;
}

FeatureExecutor &
MatchBlueprint::createExecutor(const IQueryEnvironment &env, vespalib::Stash &stash) const
{
    (void) env;
    return stash.create<MatchExecutor>(_params);
}

}
<|endoftext|>


<commit_before>#include "hext/attribute.h"

namespace hext {

attribute::attribute()
: name(),
  value(),
  is_capt(false),
  is_built(false)
{
}

bool attribute::is_capture() const
{
  return this->is_capt;
}

void attribute::set_is_capture(bool capt)
{
  this->is_capt = capt;
}

void attribute::set_name(const std::string& attribute_name)
{
  this->name = attribute_name;
  this->is_built = ( attribute_name.compare(0, 5, "hext-") == 0 );
}

void attribute::set_value(const std::string& attribute_value)
{
  this->value = attribute_value;
}

bool attribute::matches(const GumboNode * node) const
{
  if( node == nullptr )
    return false;

  if( node->type != GUMBO_NODE_ELEMENT )
    return false;

  if( this->is_built )
    return true;

  GumboAttribute * g_attr =
    gumbo_get_attribute(&node->v.element.attributes, this->name.c_str());

  if( !g_attr )
    return false;

  if( !this->is_capt && this->value.compare(g_attr->value) != 0 )
    return false;

  return true;
}

match_tree::name_value_pair
attribute::capture(const GumboNode * node) const
{
  if( node == nullptr )
    return match_tree::name_value_pair("", "");

  if( node->type != GUMBO_NODE_ELEMENT )
    return match_tree::name_value_pair("", "");

  if( this->name == "hext-inner-text" )
  {
    return match_tree::name_value_pair(
      /* name  */ this->value,
      /* value */ bc::capture_inner_text(node)
    );
  }
  else
  {
    GumboAttribute * g_attr = gumbo_get_attribute(
      &node->v.element.attributes,
      this->name.c_str()
    );
    return match_tree::name_value_pair(
      /* name  */ this->value,
      /* value */ ( g_attr && g_attr->value ? g_attr->value : "" )
    );
  }
}

void attribute::print(std::ostream& out) const
{
  out << this->name
      << "=\""
      << ( this->is_capt ? "(:" : "" )
      << this->value
      << ( this->is_capt ? ")" : "" )
      << "\"";
}

} // namespace hext

<commit_msg>condensed nullptr checks<commit_after>#include "hext/attribute.h"

namespace hext {

attribute::attribute()
: name(),
  value(),
  is_capt(false),
  is_built(false)
{
}

bool attribute::is_capture() const
{
  return this->is_capt;
}

void attribute::set_is_capture(bool capt)
{
  this->is_capt = capt;
}

void attribute::set_name(const std::string& attribute_name)
{
  this->name = attribute_name;
  this->is_built = ( attribute_name.compare(0, 5, "hext-") == 0 );
}

void attribute::set_value(const std::string& attribute_value)
{
  this->value = attribute_value;
}

bool attribute::matches(const GumboNode * node) const
{
  if( !node || node->type != GUMBO_NODE_ELEMENT )
    return false;

  if( this->is_built )
    return true;

  GumboAttribute * g_attr =
    gumbo_get_attribute(&node->v.element.attributes, this->name.c_str());

  if( !g_attr )
    return false;

  if( !this->is_capt && this->value.compare(g_attr->value) != 0 )
    return false;

  return true;
}

match_tree::name_value_pair
attribute::capture(const GumboNode * node) const
{
  if( !node || node->type != GUMBO_NODE_ELEMENT )
    return match_tree::name_value_pair("", "");

  if( this->name == "hext-inner-text" )
  {
    return match_tree::name_value_pair(
      /* name  */ this->value,
      /* value */ bc::capture_inner_text(node)
    );
  }
  else
  {
    GumboAttribute * g_attr = gumbo_get_attribute(
      &node->v.element.attributes,
      this->name.c_str()
    );
    return match_tree::name_value_pair(
      /* name  */ this->value,
      /* value */ ( g_attr && g_attr->value ? g_attr->value : "" )
    );
  }
}

void attribute::print(std::ostream& out) const
{
  out << this->name
      << "=\""
      << ( this->is_capt ? "(:" : "" )
      << this->value
      << ( this->is_capt ? ")" : "" )
      << "\"";
}

} // namespace hext

<|endoftext|>


<commit_before>#include    <cstdlib>
#include    <cmath>
#include    <fstream>
#include    <sstream>
#include    <iostream>
#include    <iomanip>
#include    <string>
#include    <vector>
#include    <algorithm>
#include    <exception>
#include    <sys/time.h>
#include    "modules/htmTree.h"
#include    "modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
    //// Initializations ---------------------------------------------
    srand48(1234); // Make sure we have reproducability
    check_args(argc);
    Time t, time; // t for global, time for local
    init_time(t);
    Feat F;
    MTL M;

    // Read parameters file //
    F.readInputFile(argv[1]);
    printFile(argv[1]);
    // Read Secretfile
    // Secret contains the identity of each target: QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF
    Gals Secret;
    init_time_at(time,"# reading Secret file",t);

        Secret=read_Secretfile(F.Secretfile,F);
    printf("# Read %d galaxies from %s \n",Secret.size(),F.Secretfile.c_str());
    print_time(time,"# ... took :");
    std::vector<int> count(10);
    count=count_galaxies(Secret);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){if(count[i]>0)printf (" type %d number  %d  \n",i, count[i]);}
    //read the three input fits files
    init_time_at(time,"# read target, SS, SF files",t);
    MTL Targ=read_MTLfile(F.Targfile,F,0,0);
    MTL SStars=read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF=read_MTLfile(F.SkyFfile,F,0,1);

    if(Targ.size() == 0) {
        std::cerr << "ERROR: No targets found in " << F.Targfile << std::endl;
        myexit(1);
    }

    print_time(time,"# ... took :");
    //combine the three input files
    M=Targ;
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" M size %d \n",M.size());
    F.Ngal=M.size();
    F.Ntarg=Secret.size();

    //establish priority classes
    init_time_at(time,"# establish priority clasess",t);
    assign_priority_class(M);
    std::vector <int> count_class(M.priority_list.size(),0);
    for(int i;i<M.size();++i){
        if(!M[i].SS&&!M[i].SF){
        count_class[M[i].priority_class]+=1;
        }
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class %d  priority %d  number %d\n",i,M.priority_list[i],count_class[i]);
    }
    print_time(time,"# ... took :");

    // fiber positioners
    PP pp;
    pp.read_fiber_positions(F);
    F.Nfiber = pp.fp.size()/2;
    F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
    pp.get_neighbors(F);
    pp.compute_fibsofsp(F);
    printf("computed neighbors\n");
    std::cout.flush();
    //P tiles in order specified by surveyFile
    Plates P = read_plate_centers(F);
    F.Nplate=P.size();
    printf("# Read %d plates from %s and %d fibers from %s\n",F.Nplate,F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

    // Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
    F.cb = create_cb(); // cb=central body
    F.fh = create_fh(); // fh=fiber holder

    //// Collect available galaxies <-> tilefibers --------------------
    // HTM Tree of galaxies
    const double MinTreeSize = 0.01;
    init_time_at(time,"# Start building HTM tree",t);

    htmTree<struct target> T(M,MinTreeSize);
    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect galaxies at ",t);

    // For plates/fibers, collect available galaxies; done in parallel
    collect_galaxies_for_all(M,T,P,pp,F);
    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect available tile-fibers at",t);
    // For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
    collect_available_tilefibers(M,P,F);

    //results_on_inputs("doc/figs/",G,P,F,true);

    //// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);

    print_time(t,"# Start assignment at : ");

    // Make a plan ----------------------------------------------------
    // Plans whole survey without sky fibers, standard stars
    // assumes maximum number of observations needed for QSOs, LRGs

    simple_assign(M,P,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    //and inverse map
    A.inv_order=initList(F.Nplate,-1);
    int inv_count=0;
    for (int j=0;j<F.Nplate ;++j){

        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){//fiber and therefore plate is used
                A.suborder.push_back(j);//suborder[jused] is jused-th used plate
                not_done=false;
                A.inv_order[j]=inv_count;//inv_order[j] is -1 unless used
                                //and otherwise the position of plate j in list of used plates
                inv_count++;
            }
        }
    }
    F.NUsedplate=A.suborder.size();
    printf(" Plates actually used %d \n",F.NUsedplate);

    if(F.diagnose)diagnostic(M,Secret,F,A);

    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs

    // Smooth out distribution of free fibers, and increase the number of assignments

    for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A,0);// more iterations will improve performance slightly
    for (int i=0; i<1; i++) {
        improve(M,P,pp,F,A,0);
        redistribute_tf(M,P,pp,F,A,0);
    }
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int jused=0;jused<F.NUsedplate;++jused){
        int j=A.suborder[jused];
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(j,M,P,pp,F,A);
    }
    if(F.diagnose)diagnostic(M,Secret,F,A);
    init_time_at(time,"# Begin real time assignment",t);

    //Execute plan, updating targets at intervals
    for(int i=0;i<F.pass_intervals.size();i++){
        printf(" i=%d interval %d \n",i,F.pass_intervals[i]);
    }
    std::vector <int> update_intervals=F.pass_intervals;
    update_intervals.push_back(F.NUsedplate);//to end intervals at last plate
    for(int i=0;i<update_intervals.size();++i){
        printf("i %d  update_interval %d\n",i, update_intervals[i]);
    }
    for(int i=0;i<update_intervals.size()-1;++i){//go plate by used plate
        int starter=update_intervals[i];
        printf("-- interval %d\n",i);
        for (int jused=starter; jused<update_intervals[i+1] && jused<A.suborder.size()-1; jused++) {

            if (0<=jused-F.Analysis) {
                update_plan_from_one_obs(jused,Secret,M,P,pp,F,A);
            }
            else printf("\n no update\n");
            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else

        }
        printf("-- redistribute %d\n",i);
        redistribute_tf(M,P,pp,F,A,starter);
        printf("-- improve %d\n",i);
        improve(M,P,pp,F,A,starter);
        printf("-- improve again %d\n",i);
        redistribute_tf(M,P,pp,F,A,starter);
        printf("-- diagnose %d\n",i);
        if(F.diagnose)diagnostic(M,Secret,F,A);

    }
    // check on SS and SF

    printf("-- Checking SS/SF\n");
    List SS_hist=initList(11,0);
    List SF_hist=initList(41,0);
    for(int jused=0;jused<F.NUsedplate;++jused){
        int j=A.suborder[jused];
        for (int p=0;p<F.Npetal;++p){
            int count_SS=0;
            int count_SF=0;
            for (int k=0;k<F.Nfbp;++k){
                int kk=pp.fibers_of_sp[p][k];
                int g=A.TF[j][kk];
                if(g!=-1 && M[g].SS)count_SS++;
                if(g!=-1 && M[g].SF)count_SF++;
            }
            SS_hist[count_SS]++;
            SF_hist[count_SF]++;
        }
    }
    printf(" SS distribution \n");
    for(int i=0;i<10;i++)printf("%8d",SS_hist[i]);
    printf("\n %8d \n",SS_hist[10]);

    printf(" SF distribution \n");
    for(int i=0;i<10;i++)printf("%8d",SF_hist[i]);
    printf("\n");
    for(int i=10;i<20;i++)printf("%8d",SF_hist[i]);
    printf("\n");
    for(int i=20;i<30;i++)printf("%8d",SF_hist[i]);
    printf("\n");
    for(int i=30;i<40;i++)printf("%8d",SF_hist[i]);
    printf("\n %8d \n",SF_hist[40]);

    // Results -------------------------------------------------------

    //special for clustering group 6/28/16
    //for each tile how many fibers free?  how many to each type of target?
    std::vector<int> free(F.NUsedplate,0);

    for (int jused=0;jused<F.NUsedplate;jused++){
        int j=A.suborder[jused];
        int this_tile=0;
        for (int k=0;k<F.Nfiber;++k){
            if (A.TF[j][k]==-1){
                this_tile+=1;
            }
        }
        free[jused]=this_tile;
    }
    FILE * FFREE;
    FFREE = fopen("free_fibers.txt","w");
    int nrows=F.NUsedplate/20 +1;
    for (int i=0;i<nrows;++i){
        for(int j=0);j<20;++j){
            fprintf(" %d ",free[20*i+j]);
        }
    }
    for (int i=nrows*20;i<F.NUsedplate;i++){
        fprintf(" %d ",free[i]);
    }

    std::vector<int> tot_free(F.NUsedplate,0);
    tot_free[0]=free[0];
    for (i=1;i<F.NUsedplate;++i){
        tot_free[i]=tot_free[i-1]+free[i];
    }
    for (int i=0;i<nrows;++i){
        for(int j=0;j<20;++j){
            fprintf(" %d ",tot_free[20*i+j]);
        }
    }
    for (int i=nrows*20;i<F.NUsedplate;i++){
        fprintf(" %d ",tot_free[i]);
    }

    if (F.PrintAscii){
        for (int jused=0; jused<F.NUsedplate; jused++){
            int j=A.suborder[jused];
            write_FAtile_ascii(A.suborder[jused],F.outDir,M,P,pp,F,A);
        }
    }

    if (F.PrintFits) {
        for (int jused=0; jused<F.NUsedplate; jused++){
            int j=A.suborder[jused];
            fa_write(A.suborder[jused],F.outDir,M,P,pp,F,A); // Write outpu
        }
    }

	display_results("doc/figs/",Secret,M,P,pp,F,A,F.Nplate,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

    print_time(t,"# Finished !... in");

    return(0);

}
<commit_msg>print number of free fibers at each tile<commit_after>#include    <cstdlib>
#include    <cmath>
#include    <fstream>
#include    <sstream>
#include    <iostream>
#include    <iomanip>
#include    <string>
#include    <vector>
#include    <algorithm>
#include    <exception>
#include    <sys/time.h>
#include    "modules/htmTree.h"
#include    "modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
    //// Initializations ---------------------------------------------
    srand48(1234); // Make sure we have reproducability
    check_args(argc);
    Time t, time; // t for global, time for local
    init_time(t);
    Feat F;
    MTL M;

    // Read parameters file //
    F.readInputFile(argv[1]);
    printFile(argv[1]);
    // Read Secretfile
    // Secret contains the identity of each target: QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF
    Gals Secret;
    init_time_at(time,"# reading Secret file",t);

        Secret=read_Secretfile(F.Secretfile,F);
    printf("# Read %d galaxies from %s \n",Secret.size(),F.Secretfile.c_str());
    print_time(time,"# ... took :");
    std::vector<int> count(10);
    count=count_galaxies(Secret);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){if(count[i]>0)printf (" type %d number  %d  \n",i, count[i]);}
    //read the three input fits files
    init_time_at(time,"# read target, SS, SF files",t);
    MTL Targ=read_MTLfile(F.Targfile,F,0,0);
    MTL SStars=read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF=read_MTLfile(F.SkyFfile,F,0,1);

    if(Targ.size() == 0) {
        std::cerr << "ERROR: No targets found in " << F.Targfile << std::endl;
        myexit(1);
    }

    print_time(time,"# ... took :");
    //combine the three input files
    M=Targ;
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" M size %d \n",M.size());
    F.Ngal=M.size();
    F.Ntarg=Secret.size();

    //establish priority classes
    init_time_at(time,"# establish priority clasess",t);
    assign_priority_class(M);
    std::vector <int> count_class(M.priority_list.size(),0);
    for(int i;i<M.size();++i){
        if(!M[i].SS&&!M[i].SF){
        count_class[M[i].priority_class]+=1;
        }
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class %d  priority %d  number %d\n",i,M.priority_list[i],count_class[i]);
    }
    print_time(time,"# ... took :");

    // fiber positioners
    PP pp;
    pp.read_fiber_positions(F);
    F.Nfiber = pp.fp.size()/2;
    F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
    pp.get_neighbors(F);
    pp.compute_fibsofsp(F);
    printf("computed neighbors\n");
    std::cout.flush();
    //P tiles in order specified by surveyFile
    Plates P = read_plate_centers(F);
    F.Nplate=P.size();
    printf("# Read %d plates from %s and %d fibers from %s\n",F.Nplate,F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

    // Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
    F.cb = create_cb(); // cb=central body
    F.fh = create_fh(); // fh=fiber holder

    //// Collect available galaxies <-> tilefibers --------------------
    // HTM Tree of galaxies
    const double MinTreeSize = 0.01;
    init_time_at(time,"# Start building HTM tree",t);

    htmTree<struct target> T(M,MinTreeSize);
    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect galaxies at ",t);

    // For plates/fibers, collect available galaxies; done in parallel
    collect_galaxies_for_all(M,T,P,pp,F);
    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect available tile-fibers at",t);
    // For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
    collect_available_tilefibers(M,P,F);

    //results_on_inputs("doc/figs/",G,P,F,true);

    //// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);

    print_time(t,"# Start assignment at : ");

    // Make a plan ----------------------------------------------------
    // Plans whole survey without sky fibers, standard stars
    // assumes maximum number of observations needed for QSOs, LRGs

    simple_assign(M,P,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    //and inverse map
    A.inv_order=initList(F.Nplate,-1);
    int inv_count=0;
    for (int j=0;j<F.Nplate ;++j){

        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){//fiber and therefore plate is used
                A.suborder.push_back(j);//suborder[jused] is jused-th used plate
                not_done=false;
                A.inv_order[j]=inv_count;//inv_order[j] is -1 unless used
                                //and otherwise the position of plate j in list of used plates
                inv_count++;
            }
        }
    }
    F.NUsedplate=A.suborder.size();
    printf(" Plates actually used %d \n",F.NUsedplate);

    if(F.diagnose)diagnostic(M,Secret,F,A);

    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs

    // Smooth out distribution of free fibers, and increase the number of assignments

    for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A,0);// more iterations will improve performance slightly
    for (int i=0; i<1; i++) {
        improve(M,P,pp,F,A,0);
        redistribute_tf(M,P,pp,F,A,0);
    }
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int jused=0;jused<F.NUsedplate;++jused){
        int j=A.suborder[jused];
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(j,M,P,pp,F,A);
    }
    if(F.diagnose)diagnostic(M,Secret,F,A);
    init_time_at(time,"# Begin real time assignment",t);

    //Execute plan, updating targets at intervals
    for(int i=0;i<F.pass_intervals.size();i++){
        printf(" i=%d interval %d \n",i,F.pass_intervals[i]);
    }
    std::vector <int> update_intervals=F.pass_intervals;
    update_intervals.push_back(F.NUsedplate);//to end intervals at last plate
    for(int i=0;i<update_intervals.size();++i){
        printf("i %d  update_interval %d\n",i, update_intervals[i]);
    }
    for(int i=0;i<update_intervals.size()-1;++i){//go plate by used plate
        int starter=update_intervals[i];
        printf("-- interval %d\n",i);
        for (int jused=starter; jused<update_intervals[i+1] && jused<A.suborder.size()-1; jused++) {

            if (0<=jused-F.Analysis) {
                update_plan_from_one_obs(jused,Secret,M,P,pp,F,A);
            }
            else printf("\n no update\n");
            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else

        }
        printf("-- redistribute %d\n",i);
        redistribute_tf(M,P,pp,F,A,starter);
        printf("-- improve %d\n",i);
        improve(M,P,pp,F,A,starter);
        printf("-- improve again %d\n",i);
        redistribute_tf(M,P,pp,F,A,starter);
        printf("-- diagnose %d\n",i);
        if(F.diagnose)diagnostic(M,Secret,F,A);

    }
    // check on SS and SF

    printf("-- Checking SS/SF\n");
    List SS_hist=initList(11,0);
    List SF_hist=initList(41,0);
    for(int jused=0;jused<F.NUsedplate;++jused){
        int j=A.suborder[jused];
        for (int p=0;p<F.Npetal;++p){
            int count_SS=0;
            int count_SF=0;
            for (int k=0;k<F.Nfbp;++k){
                int kk=pp.fibers_of_sp[p][k];
                int g=A.TF[j][kk];
                if(g!=-1 && M[g].SS)count_SS++;
                if(g!=-1 && M[g].SF)count_SF++;
            }
            SS_hist[count_SS]++;
            SF_hist[count_SF]++;
        }
    }
    printf(" SS distribution \n");
    for(int i=0;i<10;i++)printf("%8d",SS_hist[i]);
    printf("\n %8d \n",SS_hist[10]);

    printf(" SF distribution \n");
    for(int i=0;i<10;i++)printf("%8d",SF_hist[i]);
    printf("\n");
    for(int i=10;i<20;i++)printf("%8d",SF_hist[i]);
    printf("\n");
    for(int i=20;i<30;i++)printf("%8d",SF_hist[i]);
    printf("\n");
    for(int i=30;i<40;i++)printf("%8d",SF_hist[i]);
    printf("\n %8d \n",SF_hist[40]);

    // Results -------------------------------------------------------

    //special for clustering group 6/28/16
    //for each tile how many fibers free?  how many to each type of target?
    std::vector<int> free(F.NUsedplate,0);

    for (int jused=0;jused<F.NUsedplate;jused++){
        int j=A.suborder[jused];
        int this_tile=0;
        for (int k=0;k<F.Nfiber;++k){
            if (A.TF[j][k]==-1){
                this_tile+=1;
            }
        }
        free[jused]=this_tile;
    }
    FILE * FFREE;
    FFREE = fopen("free_fibers.txt","w");
    int nrows=F.NUsedplate/20 +1;
    for (int i=0;i<nrows;++i){
        for(int j=0;j<20;++j){
            fprintf(FFREE," %d ",free[20*i+j]);
        }
    }
    for (int i=nrows*20;i<F.NUsedplate;i++){
        fprintf(FFREE," %d ",free[i]);
    }

    std::vector<int> tot_free(F.NUsedplate,0);
    tot_free[0]=free[0];
    for (i=1;i<F.NUsedplate;++i){
        tot_free[i]=tot_free[i-1]+free[i];
    }
    for (int i=0;i<nrows;++i){
        for(int j=0;j<20;++j){
            fprintf(FFREE," %d ",tot_free[20*i+j]);
        }
    }
    for (int i=nrows*20;i<F.NUsedplate;i++){
        fprintf(FFREE," %d ",tot_free[i]);
    }

    if (F.PrintAscii){
        for (int jused=0; jused<F.NUsedplate; jused++){
            int j=A.suborder[jused];
            write_FAtile_ascii(A.suborder[jused],F.outDir,M,P,pp,F,A);
        }
    }

    if (F.PrintFits) {
        for (int jused=0; jused<F.NUsedplate; jused++){
            int j=A.suborder[jused];
            fa_write(A.suborder[jused],F.outDir,M,P,pp,F,A); // Write outpu
        }
    }

	display_results("doc/figs/",Secret,M,P,pp,F,A,F.Nplate,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

    print_time(t,"# Finished !... in");

    return(0);

}
<|endoftext|>


<commit_before>#include "Message.h"
#include "ClusterSession.h"

Message::Message(const std::string json_str )
{
    this->raw_data_ = nlohmann::json::parse( json_str );;

    this->status_ = this->raw_data_["status"];
    this->command_ = this->raw_data_["command"];
}

Message::Message( const std::string version, size_t command, size_t status )
{
    this->raw_data_.clear();
    this->raw_data_["command"] = command;
    this->raw_data_["status"] = status;
    this->raw_data_["version"] = version;

    this->version_ = version;
    this->status_ = status;
    this->command_ = command;
}

Message::Message( Message & message )
{
    std::string str = message.raw_data_.dump();
    this->raw_data_.parse( str );
    this->command_ = message.command_;
    this->status_ = message.status_;
    this->owner_ = message.owner_;
}

Message::Message( Message && message )
{
    this->raw_data_ = message.raw_data_;
    this->command_ = message.command_;
    this->status_ = message.status_;
    this->owner_ = message.owner_;

    message.raw_data_ = nullptr;
    message.command_ = 0;
    message.status_ = 0;
    message.owner_ = nullptr;
}

Message& Message::operator=( Message & message )
{
    std::string str = message.raw_data_;
    this->raw_data_.parse( str );
    this->command_ = message.command_;
    this->status_ = message.status_;
    this->owner_ = message.owner_;

    return *this;
}

Message & Message::operator=( Message && message )
{
    this->raw_data_ = message.raw_data_;
    this->command_ = message.command_;
    this->status_ = message.status_;
    this->owner_ = message.owner_;

    message.raw_data_ = nullptr;
    message.command_ = 0;
    message.status_ = 0;
    message.owner_ = nullptr;

    return *this;
}

Buffer Message::bytes()
{
    Buffer buffer;
    std::string json = this->raw_data_.dump();
    buffer.raw( json.c_str(), static_cast< int >( json.length() ) + 1 );

    return buffer;
}

void Message::owner( ClusterSession * session )
{
    this->owner_ = session;
}

ClusterSession * Message::owner()
{
    return this->owner_;
}
<commit_msg>fixed bugs<commit_after>#include "Message.h"
#include "ClusterSession.h"

Message::Message(const std::string json_str )
{
    this->raw_data_ = nlohmann::json::parse( json_str );;

    this->status_ = this->raw_data_["status"];
    this->command_ = this->raw_data_["command"];
}

Message::Message( const std::string version, size_t command, size_t status )
{
    this->raw_data_.clear();
    this->raw_data_["command"] = command;
    this->raw_data_["status"] = status;
    this->raw_data_["version"] = version;

    this->version_ = version;
    this->status_ = status;
    this->command_ = command;
}

Message::Message( Message & message )
{
    this->raw_data_ = nlohmann::json::parse( message.raw_data_.dump() );
    this->command_ = message.command_;
    this->status_ = message.status_;
    this->owner_ = message.owner_;
}

Message::Message( Message && message )
{
    this->raw_data_ = message.raw_data_;
    this->command_ = message.command_;
    this->status_ = message.status_;
    this->owner_ = message.owner_;

    message.raw_data_ = nullptr;
    message.command_ = 0;
    message.status_ = 0;
    message.owner_ = nullptr;
}

Message& Message::operator=( Message & message )
{
    this->raw_data_ = nlohmann::json::parse( message.raw_data_.dump() );
    this->command_ = message.command_;
    this->status_ = message.status_;
    this->owner_ = message.owner_;

    return *this;
}

Message & Message::operator=( Message && message )
{
    this->raw_data_ = message.raw_data_;
    this->command_ = message.command_;
    this->status_ = message.status_;
    this->owner_ = message.owner_;

    message.raw_data_ = nullptr;
    message.command_ = 0;
    message.status_ = 0;
    message.owner_ = nullptr;

    return *this;
}

Buffer Message::bytes()
{
    Buffer buffer;
    std::string json = this->raw_data_.dump();
    buffer.raw( json.c_str(), static_cast< int >( json.length() ) + 1 );

    return buffer;
}

void Message::owner( ClusterSession * session )
{
    this->owner_ = session;
}

ClusterSession * Message::owner()
{
    return this->owner_;
}
<|endoftext|>


<commit_before>#include "NTClient.h"
using namespace std;

NTClient::NTClient() {
	hasError = false;
	firstConnect = true;
	connected = false;
}
bool NTClient::login(string username, string password) {
	uname = username;
	pword = password;
	bool ret = true;
	string data = string("username=");
	data += uname;
	data += "&password=";
	data += pword;
	data += "&adb=1&tz=America%2FChicago"; // No need to have anything other than Chicago timezone
	httplib::SSLClient loginReq(NITROTYPE_HOSTNAME, HTTPS_PORT);
	shared_ptr<httplib::Response> res = loginReq.post(NT_LOGIN_ENDPOINT, data, "application/x-www-form-urlencoded; charset=UTF-8");
	if (res) {
		bool foundLoginCookie = false;
		for (int i = 0; i < res->cookies.size(); ++i) {
			string cookie = res->cookies.at(i);
			addCookie(Utils::extractCKey(cookie), Utils::extractCValue(cookie));
			if (cookie.find("ntuserrem=") == 0) {
				foundLoginCookie = true;
				token = Utils::extractCValue(cookie);
				cout << "Retrieved login token: " << token << endl;
				// addCookie("ntuserrem", token);
			}
		}
		if (!foundLoginCookie) {
			ret = false;
			cout << "Unable to locate the login cookie. Maybe try a different account?\n";
		}
	} else {
		ret = false;
		cout << "Login request failed. This might be a network issue. Maybe try resetting your internet connection?\n";
	}
	bool success = getPrimusSID();
	if (!success) return false;
	return ret;
}
bool NTClient::connect() {
	wsh = new Hub();
	time_t tnow = time(0);
	rawCookieStr = Utils::stringifyCookies(&cookies);
	stringstream uristream;
	uristream  << "wss://realtime1.nitrotype.com:443/realtime/?_primuscb=" << tnow << "-0&EIO=3&transport=websocket&sid=" << primusSid << "&t=" << tnow << "&b64=1";
	string wsURI = uristream.str();
	cout << "Connecting to endpoint: " << wsURI << endl;
	if (firstConnect) {
		addListeners();
	}
	// cout << "Cookies: " << rawCookieStr << endl << endl;
	// Create override headers
	SMap customHeaders;
	cout << rawCookieStr << endl;
	customHeaders["Cookie"] = rawCookieStr;
	customHeaders["Origin"] = "https://www.nitrotype.com";
	customHeaders["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36";
	// customHeaders["Host"] = "realtime1.nitrotype.com";
	wsh->connect(wsURI, (void*)this, customHeaders, 7000);
	// wsh->connect(wsURI);
	if (firstConnect) {
		wsh->run();
		firstConnect = false;
	}
	return true;
}
void NTClient::addCookie(string key, string val) {
	SPair sp = SPair(key, val);
	cookies.push_back(sp);
}
bool NTClient::getPrimusSID() {
	time_t tnow = time(0);
	rawCookieStr = Utils::stringifyCookies(&cookies);
	stringstream squery;
	squery << "?_primuscb=" << tnow << "-0&EIO=3&transport=polling&t=" << tnow << "-0&b64=1";
	string queryStr = squery.str();

	httplib::SSLClient loginReq(NT_REALTIME_HOST, HTTPS_PORT);
	string path = NT_PRIMUS_ENDPOINT + queryStr;
	shared_ptr<httplib::Response> res = loginReq.get(path.c_str(), rawCookieStr.c_str());
	if (res) {
		json jres = json::parse(res->body.substr(4, res->body.length()));
		primusSid = jres["sid"];
		cout << "Resolved primus SID: " << primusSid << endl;
		// addCookie("io", primusSid);
	} else {
		cout << "Error retrieving primus handshake data.\n";
		return false;
	}
	return true;
}
string NTClient::getJoinPacket(int avgSpeed) {
	json p = {
		{"stream", "race"},
		{"msg", "join"},
		{"payload", {
			{"debugging", false},
			{"avgSpeed", avgSpeed},
			{"track", "desert"},
			{"music", "dirty_bit"},
			{"update", 3417}
		}}
	};
	string ret = "4";
	ret += p.dump();
	return ret;
}
void NTClient::addListeners() {
	assert(wsh != nullptr);
	wsh->onError([this](void* udata) {
		cout << "Failed to connect to WebSocket server." << endl;
		hasError = true;
	});
	wsh->onConnection([this](WebSocket<CLIENT>* wsocket, HttpRequest req) {
		cout << "Connected to the realtime server." << endl;
		onConnection(wsocket, req);
	});
	wsh->onDisconnection([this](WebSocket<CLIENT>* wsocket, int code, char* msg, size_t len) {
		cout << "Disconnected from the realtime server." << endl;
		onDisconnection(wsocket, code, msg, len);
	});
	wsh->onMessage([this](WebSocket<CLIENT>* ws, char* msg, size_t len, OpCode opCode) {
		onMessage(ws, msg, len, opCode);
	});
}
void NTClient::onDisconnection(WebSocket<CLIENT>* wsocket, int code, char* msg, size_t len) {
	cout << "Disconn message: " << string(msg, len) << endl;
	cout << "Disconn code: " << code << endl;
}
void NTClient::onMessage(WebSocket<CLIENT>* ws, char* msg, size_t len, OpCode opCode) {
	cout << "ws message" << endl; // TODO: parse incoming messages
}
void NTClient::onConnection(WebSocket<CLIENT>* wsocket, HttpRequest req) {
	// Send a probe, which is required for connection
	wsocket->send("2probe", OpCode::TEXT);
	/*
	string joinTo = getJoinPacket(100); // 100 WPM just to test
	cout << joinTo << endl;
	wsocket->send(joinTo.c_str());
	*/
}<commit_msg>Ignore binary packets<commit_after>#include "NTClient.h"
using namespace std;

NTClient::NTClient() {
	hasError = false;
	firstConnect = true;
	connected = false;
}
bool NTClient::login(string username, string password) {
	uname = username;
	pword = password;
	bool ret = true;
	string data = string("username=");
	data += uname;
	data += "&password=";
	data += pword;
	data += "&adb=1&tz=America%2FChicago"; // No need to have anything other than Chicago timezone
	httplib::SSLClient loginReq(NITROTYPE_HOSTNAME, HTTPS_PORT);
	shared_ptr<httplib::Response> res = loginReq.post(NT_LOGIN_ENDPOINT, data, "application/x-www-form-urlencoded; charset=UTF-8");
	if (res) {
		bool foundLoginCookie = false;
		for (int i = 0; i < res->cookies.size(); ++i) {
			string cookie = res->cookies.at(i);
			addCookie(Utils::extractCKey(cookie), Utils::extractCValue(cookie));
			if (cookie.find("ntuserrem=") == 0) {
				foundLoginCookie = true;
				token = Utils::extractCValue(cookie);
				cout << "Retrieved login token: " << token << endl;
				// addCookie("ntuserrem", token);
			}
		}
		if (!foundLoginCookie) {
			ret = false;
			cout << "Unable to locate the login cookie. Maybe try a different account?\n";
		}
	} else {
		ret = false;
		cout << "Login request failed. This might be a network issue. Maybe try resetting your internet connection?\n";
	}
	bool success = getPrimusSID();
	if (!success) return false;
	return ret;
}
bool NTClient::connect() {
	wsh = new Hub();
	time_t tnow = time(0);
	rawCookieStr = Utils::stringifyCookies(&cookies);
	stringstream uristream;
	uristream  << "wss://realtime1.nitrotype.com:443/realtime/?_primuscb=" << tnow << "-0&EIO=3&transport=websocket&sid=" << primusSid << "&t=" << tnow << "&b64=1";
	string wsURI = uristream.str();
	cout << "Connecting to endpoint: " << wsURI << endl;
	if (firstConnect) {
		addListeners();
	}
	// cout << "Cookies: " << rawCookieStr << endl << endl;
	// Create override headers
	SMap customHeaders;
	cout << rawCookieStr << endl;
	customHeaders["Cookie"] = rawCookieStr;
	customHeaders["Origin"] = "https://www.nitrotype.com";
	customHeaders["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36";
	// customHeaders["Host"] = "realtime1.nitrotype.com";
	wsh->connect(wsURI, (void*)this, customHeaders, 7000);
	// wsh->connect(wsURI);
	if (firstConnect) {
		wsh->run();
		firstConnect = false;
	}
	return true;
}
void NTClient::addCookie(string key, string val) {
	SPair sp = SPair(key, val);
	cookies.push_back(sp);
}
bool NTClient::getPrimusSID() {
	time_t tnow = time(0);
	rawCookieStr = Utils::stringifyCookies(&cookies);
	stringstream squery;
	squery << "?_primuscb=" << tnow << "-0&EIO=3&transport=polling&t=" << tnow << "-0&b64=1";
	string queryStr = squery.str();

	httplib::SSLClient loginReq(NT_REALTIME_HOST, HTTPS_PORT);
	string path = NT_PRIMUS_ENDPOINT + queryStr;
	shared_ptr<httplib::Response> res = loginReq.get(path.c_str(), rawCookieStr.c_str());
	if (res) {
		json jres = json::parse(res->body.substr(4, res->body.length()));
		primusSid = jres["sid"];
		cout << "Resolved primus SID: " << primusSid << endl;
		// addCookie("io", primusSid);
	} else {
		cout << "Error retrieving primus handshake data.\n";
		return false;
	}
	return true;
}
string NTClient::getJoinPacket(int avgSpeed) {
	json p = {
		{"stream", "race"},
		{"msg", "join"},
		{"payload", {
			{"debugging", false},
			{"avgSpeed", avgSpeed},
			{"track", "desert"},
			{"music", "dirty_bit"},
			{"update", 3417}
		}}
	};
	string ret = "4";
	ret += p.dump();
	return ret;
}
void NTClient::addListeners() {
	assert(wsh != nullptr);
	wsh->onError([this](void* udata) {
		cout << "Failed to connect to WebSocket server." << endl;
		hasError = true;
	});
	wsh->onConnection([this](WebSocket<CLIENT>* wsocket, HttpRequest req) {
		cout << "Connected to the realtime server." << endl;
		onConnection(wsocket, req);
	});
	wsh->onDisconnection([this](WebSocket<CLIENT>* wsocket, int code, char* msg, size_t len) {
		cout << "Disconnected from the realtime server." << endl;
		onDisconnection(wsocket, code, msg, len);
	});
	wsh->onMessage([this](WebSocket<CLIENT>* ws, char* msg, size_t len, OpCode opCode) {
		onMessage(ws, msg, len, opCode);
	});
}
void NTClient::onDisconnection(WebSocket<CLIENT>* wsocket, int code, char* msg, size_t len) {
	cout << "Disconn message: " << string(msg, len) << endl;
	cout << "Disconn code: " << code << endl;
}
void NTClient::onMessage(WebSocket<CLIENT>* ws, char* msg, size_t len, OpCode opCode) {
	if (OpCode != OpCode::TEXT) {
		cout << "The server did not send a text packet, ignoring.\n";
		return;
	}
	cout << "ws message" << endl; // TODO: parse incoming messages
}
void NTClient::onConnection(WebSocket<CLIENT>* wsocket, HttpRequest req) {
	// Send a probe, which is required for connection
	wsocket->send("2probe", OpCode::TEXT);
	/*
	string joinTo = getJoinPacket(100); // 100 WPM just to test
	cout << joinTo << endl;
	wsocket->send(joinTo.c_str());
	*/
}<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// 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)
//=======================================================================

#include "tac/Utils.hpp"

using namespace eddic;

void eddic::tac::computeBlockUsage(std::shared_ptr<tac::Function> function, std::unordered_set<std::shared_ptr<tac::BasicBlock>>& usage){
    for(auto& block : function->getBasicBlocks()){
        for(auto& statement : block->statements){
            if(auto* ptr = boost::get<std::shared_ptr<tac::Goto>>(&statement)){
                usage.insert((*ptr)->block);
            } else if(auto* ptr = boost::get<std::shared_ptr<tac::IfFalse>>(&statement)){
                usage.insert((*ptr)->block);
            } else if(auto* ptr = boost::get<std::shared_ptr<tac::If>>(&statement)){
                usage.insert((*ptr)->block);
            }
        }
    }
}

bool eddic::tac::safe(std::shared_ptr<tac::Call> call){
    auto function = call->function;

    //These three functions are considered as safe because they save/restore all the registers and does not return anything
    return function == "print_integer" || function == "print_string" || function == "print_line";
}
<commit_msg>Fix the safe functions calculations function to handle the new function names<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// 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)
//=======================================================================

#include "tac/Utils.hpp"

using namespace eddic;

void eddic::tac::computeBlockUsage(std::shared_ptr<tac::Function> function, std::unordered_set<std::shared_ptr<tac::BasicBlock>>& usage){
    for(auto& block : function->getBasicBlocks()){
        for(auto& statement : block->statements){
            if(auto* ptr = boost::get<std::shared_ptr<tac::Goto>>(&statement)){
                usage.insert((*ptr)->block);
            } else if(auto* ptr = boost::get<std::shared_ptr<tac::IfFalse>>(&statement)){
                usage.insert((*ptr)->block);
            } else if(auto* ptr = boost::get<std::shared_ptr<tac::If>>(&statement)){
                usage.insert((*ptr)->block);
            }
        }
    }
}

bool eddic::tac::safe(std::shared_ptr<tac::Call> call){
    auto function = call->function;

    //These functions are considered as safe because they save/restore all the registers and does not return anything
    return
        function == "_F5printB" || function == "_F5printI" || function == "_F5printS" ||
        function == "_F7printlnB" || function == "_F7printlnI" || function == "_F7printlnS" ||
        function == "_F7println";
}
<|endoftext|>


<commit_before>/*
 * TCP client connection pooling.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#ifndef BENG_PROXY_TCP_STOCK_HXX
#define BENG_PROXY_TCP_STOCK_HXX

#include <inline/compiler.h>

struct pool;
struct balancer;
struct StockMap;
struct StockItem;
class StockGetHandler;
struct async_operation_ref;
class SocketAddress;

/**
 * Creates a new TCP connection stock.
 *
 * @param limit the maximum number of connections per host
 * @return the new TCP connections stock (this function cannot fail)
 */
StockMap *
tcp_stock_new(unsigned limit);

/**
 * @param name the hstock name; it is auto-generated from the
 * #address_list if NULL is passed here
 * @param timeout the connect timeout in seconds
 */
void
tcp_stock_get(StockMap *tcp_stock, struct pool *pool, const char *name,
              bool ip_transparent,
              SocketAddress bind_address,
              SocketAddress address,
              unsigned timeout,
              StockGetHandler &handler,
              struct async_operation_ref &async_ref);

gcc_pure
int
tcp_stock_item_get(const StockItem &item);

gcc_pure
int
tcp_stock_item_get_domain(const StockItem &item);

gcc_pure
const char *
tcp_stock_item_get_name(const StockItem &item);

#endif
<commit_msg>tcp_stock: update API documentation<commit_after>/*
 * TCP client connection pooling.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#ifndef BENG_PROXY_TCP_STOCK_HXX
#define BENG_PROXY_TCP_STOCK_HXX

#include <inline/compiler.h>

struct pool;
struct balancer;
struct StockMap;
struct StockItem;
class StockGetHandler;
struct async_operation_ref;
class SocketAddress;

/**
 * Creates a new TCP connection stock.
 *
 * @param limit the maximum number of connections per host
 * @return the new TCP connections stock (this function cannot fail)
 */
StockMap *
tcp_stock_new(unsigned limit);

/**
 * @param name the MapStock name; it is auto-generated from the
 * #address if nullptr is passed here
 * @param timeout the connect timeout in seconds
 */
void
tcp_stock_get(StockMap *tcp_stock, struct pool *pool, const char *name,
              bool ip_transparent,
              SocketAddress bind_address,
              SocketAddress address,
              unsigned timeout,
              StockGetHandler &handler,
              struct async_operation_ref &async_ref);

gcc_pure
int
tcp_stock_item_get(const StockItem &item);

gcc_pure
int
tcp_stock_item_get_domain(const StockItem &item);

gcc_pure
const char *
tcp_stock_item_get_name(const StockItem &item);

#endif
<|endoftext|>