<commit_before>// Scintilla source code edit control
/** @file KeyWords.cxx
 ** Colourise for particular languages.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

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

#include "Platform.h"

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

LexerModule *LexerModule::base = 0;
int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;

LexerModule::LexerModule(int language_, LexerFunction fnLexer_,
	const char *languageName_, LexerFunction fnFolder_) :
	language(language_),
	languageName(languageName_),
	fnLexer(fnLexer_),
	fnFolder(fnFolder_) {
	next = base;
	base = this;
	if (language == SCLEX_AUTOMATIC) {
		language = nextLanguage;
		nextLanguage++;
	}
}

LexerModule *LexerModule::Find(int language) {
	LexerModule *lm = base;
	while (lm) {
		if (lm->language == language) {
			return lm;
		}
		lm = lm->next;
	}
	return 0;
}

LexerModule *LexerModule::Find(const char *languageName) {
	if (languageName) {
		LexerModule *lm = base;
		while (lm) {
			if (lm->languageName && 0 == strcmp(lm->languageName, languageName)) {
				return lm;
			}
			lm = lm->next;
		}
	}
	return 0;
}

void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
	  WordList *keywordlists[], Accessor &styler) {
	if (fnLexer)
		fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
}

void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
	  WordList *keywordlists[], Accessor &styler) {
	if (fnFolder) {
		int lineCurrent = styler.GetLine(startPos);
		// Move back one line in case deletion wrecked current line fold state
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
		fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
	}
}

static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[],
                            Accessor &styler) {
	// Null language means all style bytes are 0 so just mark the end - no need to fill in.
	if (length > 0) {
		styler.StartAt(startPos + length - 1);
		styler.StartSegment(startPos + length - 1);
		styler.ColourTo(startPos + length - 1, 0);
	}
}

LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null");

#ifdef __vms

// The following code forces a reference to all of the Scintilla lexers.
// If we don't do something like this, then the linker tends to "optimize"
// them away. (eric@sourcegear.com)

// Taken from wxWindow's stc.cpp. Walter.

int wxForceScintillaLexers(void) {
  extern LexerModule lmAda;
  extern LexerModule lmAVE;
  extern LexerModule lmConf;
  extern LexerModule lmDiff;
  extern LexerModule lmLatex;
  extern LexerModule lmPascal;
  extern LexerModule lmCPP;
  extern LexerModule lmHTML;
  extern LexerModule lmXML;
  extern LexerModule lmProps;
  extern LexerModule lmErrorList;
  extern LexerModule lmMake;
  extern LexerModule lmBatch;
  extern LexerModule lmPerl;
  extern LexerModule lmPython;
  extern LexerModule lmSQL;
  extern LexerModule lmVB;
  extern LexerModule lmRuby;

  if (
      &lmAda
      && &lmAVE
      && &lmConf
      && &lmDiff
      && &lmLatex
      && &lmPascal
      && &lmCPP
      && &lmHTML
      && &lmXML
      && &lmProps
      && &lmErrorList
      && &lmMake
      && &lmBatch
      && &lmPerl
      && &lmPython
      && &lmSQL
      && &lmVB
      && &lmRuby
      )
    {
      return 1;
    }
  else
    {
      return 0;
    }
}
#endif
<commit_msg>Fixed up length to fold and initial style perturbed when making fold start one line early.<commit_after>// Scintilla source code edit control
/** @file KeyWords.cxx
 ** Colourise for particular languages.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

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

#include "Platform.h"

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

LexerModule *LexerModule::base = 0;
int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;

LexerModule::LexerModule(int language_, LexerFunction fnLexer_,
	const char *languageName_, LexerFunction fnFolder_) :
	language(language_),
	languageName(languageName_),
	fnLexer(fnLexer_),
	fnFolder(fnFolder_) {
	next = base;
	base = this;
	if (language == SCLEX_AUTOMATIC) {
		language = nextLanguage;
		nextLanguage++;
	}
}

LexerModule *LexerModule::Find(int language) {
	LexerModule *lm = base;
	while (lm) {
		if (lm->language == language) {
			return lm;
		}
		lm = lm->next;
	}
	return 0;
}

LexerModule *LexerModule::Find(const char *languageName) {
	if (languageName) {
		LexerModule *lm = base;
		while (lm) {
			if (lm->languageName && 0 == strcmp(lm->languageName, languageName)) {
				return lm;
			}
			lm = lm->next;
		}
	}
	return 0;
}

void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
	  WordList *keywordlists[], Accessor &styler) {
	if (fnLexer)
		fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
}

void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
	  WordList *keywordlists[], Accessor &styler) {
	if (fnFolder) {
		int lineCurrent = styler.GetLine(startPos);
		// Move back one line in case deletion wrecked current line fold state
		if (lineCurrent > 0) {
			lineCurrent--;
			int newStartPos = styler.LineStart(lineCurrent);
			lengthDoc += startPos - newStartPos;
			startPos = newStartPos;
			initStyle = 0;
			if (startPos > 0) {
				initStyle = styler.StyleAt(startPos - 1);
			}
		}
		fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
	}
}

static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[],
                            Accessor &styler) {
	// Null language means all style bytes are 0 so just mark the end - no need to fill in.
	if (length > 0) {
		styler.StartAt(startPos + length - 1);
		styler.StartSegment(startPos + length - 1);
		styler.ColourTo(startPos + length - 1, 0);
	}
}

LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null");

#ifdef __vms

// The following code forces a reference to all of the Scintilla lexers.
// If we don't do something like this, then the linker tends to "optimize"
// them away. (eric@sourcegear.com)

// Taken from wxWindow's stc.cpp. Walter.

int wxForceScintillaLexers(void) {
  extern LexerModule lmAda;
  extern LexerModule lmAVE;
  extern LexerModule lmConf;
  extern LexerModule lmDiff;
  extern LexerModule lmLatex;
  extern LexerModule lmPascal;
  extern LexerModule lmCPP;
  extern LexerModule lmHTML;
  extern LexerModule lmXML;
  extern LexerModule lmProps;
  extern LexerModule lmErrorList;
  extern LexerModule lmMake;
  extern LexerModule lmBatch;
  extern LexerModule lmPerl;
  extern LexerModule lmPython;
  extern LexerModule lmSQL;
  extern LexerModule lmVB;
  extern LexerModule lmRuby;

  if (
      &lmAda
      && &lmAVE
      && &lmConf
      && &lmDiff
      && &lmLatex
      && &lmPascal
      && &lmCPP
      && &lmHTML
      && &lmXML
      && &lmProps
      && &lmErrorList
      && &lmMake
      && &lmBatch
      && &lmPerl
      && &lmPython
      && &lmSQL
      && &lmVB
      && &lmRuby
      )
    {
      return 1;
    }
  else
    {
      return 0;
    }
}
#endif
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexCrontab.cxx
 ** Lexer to use with extended crontab files used by a powerful
 ** Windows scheduler/event monitor/automation manager nnCron.
 ** (http://nemtsev.eserv.ru/)
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

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

#include "Platform.h"

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

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

bool is_whitespace(int ch){
    return ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ';
}

bool is_blank(int ch){
    return ch == '\t' || ch == ' ';
}
//#define FORTH_DEBUG
#ifdef FORTH_DEBUG
static FILE *f_debug;
#define log(x)  fputs(f_debug,x);
#else
#define log(x)
#endif

#define STATE_LOCALE
#define BL ' '

static Accessor *st;
static int cur_pos,pos1,pos2,pos0,lengthDoc;
char *buffer;

char getChar(bool is_bl){
    char ch=st->SafeGetCharAt(cur_pos);
    if(is_bl) if(is_whitespace(ch)) ch=BL;
    return ch;
}

char getCharBL(){
    char ch=st->SafeGetCharAt(cur_pos);
    return ch;
}
bool is_eol(char ch){
    return ch=='\n' || ch=='\r';
}

int parse(char ch, bool skip_eol){
// pos1 - start pos of word
// pos2 - pos after of word
// pos0 - start pos
    char c=0;
    int len;
    bool is_bl=ch==BL;
    pos0=pos1=pos2=cur_pos;
    for(;cur_pos<lengthDoc && (c=getChar(is_bl))==ch; cur_pos++){
        if(is_eol(c) && !skip_eol){
            pos2=pos1;
            return 0;
        }
    }
    pos1=cur_pos;
    pos2=pos1;
    if(cur_pos==lengthDoc) return 0;
    for(len=0;cur_pos<lengthDoc && (c=getChar(is_bl))!=ch; cur_pos++){
        if(is_eol(c) && !skip_eol) break;
        pos2++;
        buffer[len++]=c;
    }
    if(c==ch) pos2--;
    buffer[len]='\0';
#ifdef FORTH_DEBUG
    fprintf(f_debug,"parse: %c %s\n",ch,buffer);
#endif
    return len;
}

bool _is_number(char *s,int base){
    for(;*s;s++){
        int digit=((int)*s)-(int)'0';
#ifdef FORTH_DEBUG
    fprintf(f_debug,"digit: %c %d\n",*s,digit);
#endif
        if(digit>9 && base>10) digit-=7;
        if(digit<0) return false;
        if(digit>=base) return false;
    }
    return true;
}

bool is_number(char *s){
    if(strncmp(s,"0x",2)==0) return _is_number(s+2,16);
    return _is_number(s,10);
}

static void ColouriseForthDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
{
    st=&styler;
    cur_pos=startPos;
    lengthDoc = startPos + length;
    buffer = new char[length];

#ifdef FORTH_DEBUG
    f_debug=fopen("c:\\sci.log","at");
#endif

    WordList &control = *keywordLists[0];
    WordList &keyword = *keywordLists[1];
    WordList &defword = *keywordLists[2];
    WordList &preword1 = *keywordLists[3];
    WordList &preword2 = *keywordLists[4];
    WordList &strings = *keywordLists[5];

    // go through all provided text segment
    // using the hand-written state machine shown below
    styler.StartAt(startPos);
    styler.StartSegment(startPos);
    while(parse(BL,true)!=0){
        if(pos0!=pos1){
            styler.ColourTo(pos0,SCE_FORTH_DEFAULT);
            styler.ColourTo(pos1-1,SCE_FORTH_DEFAULT);
        }
        if(strcmp("\\",buffer)==0){
            styler.ColourTo(pos1,SCE_FORTH_COMMENT);
            parse(1,false);
            styler.ColourTo(pos2,SCE_FORTH_COMMENT);
        }else if(strcmp("(",buffer)==0){
            styler.ColourTo(pos1,SCE_FORTH_COMMENT);
            parse(')',true);
            if(cur_pos<lengthDoc) cur_pos++;
            styler.ColourTo(cur_pos,SCE_FORTH_COMMENT);
        }else if(strcmp("[",buffer)==0){
            styler.ColourTo(pos1,SCE_FORTH_STRING);
            parse(']',true);
            if(cur_pos<lengthDoc) cur_pos++;
            styler.ColourTo(cur_pos,SCE_FORTH_STRING);
        }else if(strcmp("{",buffer)==0){
            styler.ColourTo(pos1,SCE_FORTH_LOCALE);
            parse('}',false);
            if(cur_pos<lengthDoc) cur_pos++;
            styler.ColourTo(cur_pos,SCE_FORTH_LOCALE);
        }else if(strings.InList(buffer)) {
            styler.ColourTo(pos1,SCE_FORTH_STRING);
            parse('"',false);
            if(cur_pos<lengthDoc) cur_pos++;
            styler.ColourTo(cur_pos,SCE_FORTH_STRING);
        }else if(control.InList(buffer)) {
            styler.ColourTo(pos1,SCE_FORTH_CONTROL);
            styler.ColourTo(pos2,SCE_FORTH_CONTROL);
        }else if(keyword.InList(buffer)) {
            styler.ColourTo(pos1,SCE_FORTH_KEYWORD);
            styler.ColourTo(pos2,SCE_FORTH_KEYWORD);
        }else if(defword.InList(buffer)) {
            styler.ColourTo(pos1,SCE_FORTH_KEYWORD);
            styler.ColourTo(pos2,SCE_FORTH_KEYWORD);
            parse(BL,false);
            styler.ColourTo(pos1-1,SCE_FORTH_DEFAULT);
            styler.ColourTo(pos1,SCE_FORTH_DEFWORD);
            styler.ColourTo(pos2,SCE_FORTH_DEFWORD);
        }else if(preword1.InList(buffer)) {
            styler.ColourTo(pos1,SCE_FORTH_PREWORD1);
            parse(BL,false);
            styler.ColourTo(pos2,SCE_FORTH_PREWORD1);
        }else if(preword2.InList(buffer)) {
            styler.ColourTo(pos1,SCE_FORTH_PREWORD2);
            parse(BL,false);
            styler.ColourTo(pos2,SCE_FORTH_PREWORD2);
            parse(BL,false);
            styler.ColourTo(pos1,SCE_FORTH_STRING);
            styler.ColourTo(pos2,SCE_FORTH_STRING);
        }else if(is_number(buffer)){
            styler.ColourTo(pos1,SCE_FORTH_NUMBER);
            styler.ColourTo(pos2,SCE_FORTH_NUMBER);
        }
    }
#ifdef FORTH_DEBUG
    fclose(f_debug);
#endif
    delete []buffer;
    return;
/*
                        if(control.InList(buffer)) {
                            styler.ColourTo(i,SCE_FORTH_CONTROL);
                        } else if(keyword.InList(buffer)) {
                            styler.ColourTo(i-1,SCE_FORTH_KEYWORD );
                        } else if(defword.InList(buffer)) {
                            styler.ColourTo(i-1,SCE_FORTH_DEFWORD );
//                            prev_state=SCE_FORTH_DEFWORD
                        } else if(preword1.InList(buffer)) {
                            styler.ColourTo(i-1,SCE_FORTH_PREWORD1 );
//                            state=SCE_FORTH_PREWORD1;
                        } else if(preword2.InList(buffer)) {
                            styler.ColourTo(i-1,SCE_FORTH_PREWORD2 );
                         } else {
                            styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
                        }
*/
/*
    chPrev=' ';
    for (int i = startPos; i < lengthDoc; i++) {
        char ch = chNext;
        chNext = styler.SafeGetCharAt(i + 1);
        if(i!=startPos) chPrev=styler.SafeGetCharAt(i - 1);

        if (styler.IsLeadByte(ch)) {
            chNext = styler.SafeGetCharAt(i + 2);
            i++;
            continue;
        }
#ifdef FORTH_DEBUG
        fprintf(f_debug,"%c %d ",ch,state);
#endif
        switch(state) {
            case SCE_FORTH_DEFAULT:
                if(is_whitespace(ch)) {
                    // whitespace is simply ignored here...
                    styler.ColourTo(i,SCE_FORTH_DEFAULT);
                    break;
                } else if( ch == '\\' && is_blank(chNext)) {
                    // signals the start of an one line comment...
                    state = SCE_FORTH_COMMENT;
                    styler.ColourTo(i,SCE_FORTH_COMMENT);
                } else if( is_whitespace(chPrev) &&  ch == '(' &&  is_whitespace(chNext)) {
                    // signals the start of a plain comment...
                    state = SCE_FORTH_COMMENT_ML;
                    styler.ColourTo(i,SCE_FORTH_COMMENT_ML);
                } else if( isdigit(ch) ) {
                    // signals the start of a number
                    bufferCount = 0;
                    buffer[bufferCount++] = ch;
                    state = SCE_FORTH_NUMBER;
                } else if( !is_whitespace(ch)) {
                    // signals the start of an identifier
                    bufferCount = 0;
                    buffer[bufferCount++] = ch;
                    state = SCE_FORTH_IDENTIFIER;
                } else {
                    // style it the default style..
                    styler.ColourTo(i,SCE_FORTH_DEFAULT);
                }
                break;

            case SCE_FORTH_COMMENT:
                // if we find a newline here,
                // we simply go to default state
                // else continue to work on it...
                if( ch == '\n' || ch == '\r' ) {
                    state = SCE_FORTH_DEFAULT;
                } else {
                    styler.ColourTo(i,SCE_FORTH_COMMENT);
                }
                break;

            case SCE_FORTH_COMMENT_ML:
                if( ch == ')') {
                    state = SCE_FORTH_DEFAULT;
                } else {
                    styler.ColourTo(i+1,SCE_FORTH_COMMENT_ML);
                }
                break;

            case SCE_FORTH_IDENTIFIER:
                // stay  in CONF_IDENTIFIER state until we find a non-alphanumeric
                if( !is_whitespace(ch) ) {
                    buffer[bufferCount++] = ch;
                } else {
                    state = SCE_FORTH_DEFAULT;
                    buffer[bufferCount] = '\0';
#ifdef FORTH_DEBUG
        fprintf(f_debug,"\nid %s\n",buffer);
#endif

                    // check if the buffer contains a keyword,
                    // and highlight it if it is a keyword...
//                    switch(prev_state)
//                    case SCE_FORTH_DEFAULT:
                        if(control.InList(buffer)) {
                            styler.ColourTo(i,SCE_FORTH_CONTROL);
                        } else if(keyword.InList(buffer)) {
                            styler.ColourTo(i-1,SCE_FORTH_KEYWORD );
                        } else if(defword.InList(buffer)) {
                            styler.ColourTo(i-1,SCE_FORTH_DEFWORD );
//                            prev_state=SCE_FORTH_DEFWORD
                        } else if(preword1.InList(buffer)) {
                            styler.ColourTo(i-1,SCE_FORTH_PREWORD1 );
//                            state=SCE_FORTH_PREWORD1;
                        } else if(preword2.InList(buffer)) {
                            styler.ColourTo(i-1,SCE_FORTH_PREWORD2 );
                         } else {
                            styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
                        }
//                        break;
//                    case

                    // push back the faulty character
                    chNext = styler[i--];
                }
                break;

            case SCE_FORTH_NUMBER:
                // stay  in CONF_NUMBER state until we find a non-numeric
                if( isdigit(ch) ) {
                    buffer[bufferCount++] = ch;
                } else {
                    state = SCE_FORTH_DEFAULT;
                    buffer[bufferCount] = '\0';
                    // Colourize here... (normal number)
                    styler.ColourTo(i-1,SCE_FORTH_NUMBER);
                    // push back a character
                    chNext = styler[i--];
                }
                break;
        }
    }
#ifdef FORTH_DEBUG
    fclose(f_debug);
#endif
    delete []buffer;
*/
}

static void FoldForthDoc(unsigned int, int, int, WordList *[],
                       Accessor &) {
}

static const char * const forthWordLists[] = {
            "control keywords",
            "keywords",
            "definition words",
            "prewords with one argument",
            "prewords with two arguments",
            "string definition keywords",
            0,
        };

LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth",FoldForthDoc,forthWordLists);
<commit_msg>New FORTH lexer from bug #2804894.<commit_after>// Scintilla source code edit control
/** @file LexForth.cxx
 ** Lexer for FORTH
 **/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

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

#include "Platform.h"

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

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static inline bool IsAWordChar(int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
		ch == '_' || ch == '?' || ch == '"' || ch == '@' ||
		ch == '!' || ch == '[' || ch == ']' || ch == '/' ||
		ch == '+' || ch == '-' || ch == '*' || ch == '<' ||
		ch == '>' || ch == '=' || ch == ';' || ch == '(' ||
		ch == ')' );
}

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

static inline bool IsANumChar(int ch) {
	return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
}

static inline bool IsASpaceChar(int ch) {
	return (ch < 0x80) && isspace(ch);
}

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

    WordList &control = *keywordLists[0];
    WordList &keyword = *keywordLists[1];
    WordList &defword = *keywordLists[2];
    WordList &preword1 = *keywordLists[3];
    WordList &preword2 = *keywordLists[4];
    WordList &strings = *keywordLists[5];

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

	for (; sc.More(); sc.Forward())
	{
		// Determine if the current state should terminate.
		if (sc.state == SCE_FORTH_COMMENT) {
			if (sc.atLineEnd) {
				sc.SetState(SCE_FORTH_DEFAULT);
			}
		}else if (sc.state == SCE_FORTH_COMMENT_ML) {
			if (sc.ch == ')') {
				sc.ForwardSetState(SCE_FORTH_DEFAULT);
			}
		}else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {
			// handle numbers here too, because what we thought was a number might
			// turn out to be a keyword e.g. 2DUP
			if (IsASpaceChar(sc.ch) ) {
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;
				if (control.InList(s)) {
					sc.ChangeState(SCE_FORTH_CONTROL);
				} else if (keyword.InList(s)) {
					sc.ChangeState(SCE_FORTH_KEYWORD);
				} else if (defword.InList(s)) {
					sc.ChangeState(SCE_FORTH_DEFWORD);
				}  else if (preword1.InList(s)) {
					sc.ChangeState(SCE_FORTH_PREWORD1);
				} else if (preword2.InList(s)) {
					sc.ChangeState(SCE_FORTH_PREWORD2);
				} else if (strings.InList(s)) {
					sc.ChangeState(SCE_FORTH_STRING);
					newState = SCE_FORTH_STRING;
				}
				sc.SetState(newState);
			}
			if (sc.state == SCE_FORTH_NUMBER) {
				if (IsASpaceChar(sc.ch)) {
					sc.SetState(SCE_FORTH_DEFAULT);
				}
			}
		}else if (sc.state == SCE_FORTH_STRING) {
			if (sc.ch == '\"') {
				sc.ForwardSetState(SCE_FORTH_DEFAULT);
			}
		}else if (sc.state == SCE_FORTH_LOCALE) {
			if (sc.ch == '}') {
				sc.ForwardSetState(SCE_FORTH_DEFAULT);
			}
		}else if (sc.state == SCE_FORTH_DEFWORD) {
			if (IsASpaceChar(sc.ch)) {
				sc.SetState(SCE_FORTH_DEFAULT);
			}
		}

		// Determine if a new state should be entered.
		if (sc.state == SCE_FORTH_DEFAULT) {
			if (sc.ch == '\\'){
				sc.SetState(SCE_FORTH_COMMENT);
			} else if (sc.ch == '(' &&
					(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
					(sc.atLineEnd   || IsASpaceChar(sc.chNext))) {
				sc.SetState(SCE_FORTH_COMMENT_ML);
			} else if (	(sc.ch == '$' && (isascii(sc.chNext) && isxdigit(sc.chNext))) ) {
				// number starting with $ is a hex number
				sc.SetState(SCE_FORTH_NUMBER);
				while(sc.More() && isascii(sc.chNext) && isxdigit(sc.chNext))
					sc.Forward();
			} else if ( (sc.ch == '%' && (isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {
				// number starting with % is binary
				sc.SetState(SCE_FORTH_NUMBER);
				while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
					sc.Forward();
			} else if (	isascii(sc.ch) &&
						(isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
					){
				sc.SetState(SCE_FORTH_NUMBER);
			} else if (IsAWordStart(sc.ch)) {
				sc.SetState(SCE_FORTH_IDENTIFIER);
			} else if (sc.ch == '{') {
				sc.SetState(SCE_FORTH_LOCALE);
			} else if (sc.ch == ':' && isascii(sc.chNext) && isspace(sc.chNext)) {
				// highlight word definitions e.g.  : GCD ( n n -- n ) ..... ;
				//                                  ^ ^^^
				sc.SetState(SCE_FORTH_DEFWORD);
				while(sc.More() && isascii(sc.chNext) && isspace(sc.chNext))
					sc.Forward();
			} else if (sc.ch == ';' &&
					(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
					(sc.atLineEnd   || IsASpaceChar(sc.chNext))	) {
				// mark the ';' that ends a word
				sc.SetState(SCE_FORTH_DEFWORD);
				sc.ForwardSetState(SCE_FORTH_DEFAULT);
			}
		}

	}
	sc.Complete();
}

static void FoldForthDoc(unsigned int, int, int, WordList *[],
						Accessor &) {
}

static const char * const forthWordLists[] = {
			"control keywords",
			"keywords",
			"definition words",
			"prewords with one argument",
			"prewords with two arguments",
			"string definition keywords",
			0,
		};

LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);

<|endoftext|>


<commit_before>#include <util/atomic.h>
#include <SoftWire.h>
#include <AsyncDelay.h>

// Force SDA low
void SoftWire::setSdaLow(const SoftWire *p)
{
	uint8_t sda = p->getSda();
	// Disable interrupts whilst switching pin direction
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
		digitalWrite(sda, LOW);
		pinMode(sda, OUTPUT);
	}
}

// Release SDA to float high
void SoftWire::setSdaHigh(const SoftWire *p)
{
	pinMode(p->getSda(), p->getInputMode());
}

// Force SCL low
void SoftWire::setSclLow(const SoftWire *p)
{
	uint8_t scl = p->getScl();
	// Disable interrupts whilst switching pin direction
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
		digitalWrite(scl, LOW);
		pinMode(scl, OUTPUT);
	}
}

// Release SCL to float high
void SoftWire::setSclHigh(const SoftWire *p)
{
	pinMode(p->getScl(), p->getInputMode());
}

// Read SDA (for data read)
uint8_t SoftWire::readSda(const SoftWire *p)
{
	return digitalRead(p->getSda());
}

// Read SCL (to detect clock-stretching)
uint8_t SoftWire::readScl(const SoftWire *p)
{
	return digitalRead(p->getScl());
}

// For testing the CRC-8 calculator may be useful:
// http://smbus.org/faq/crc8Applet.htm
uint8_t SoftWire::crc8_update(uint8_t crc, uint8_t data)
{
	const uint16_t polynomial = 0x107;
	crc ^= data;
	for (uint8_t i = 8; i; --i) {
		if (crc & 0x80)
			crc = (uint16_t(crc) << 1) ^ polynomial;
		else
			crc <<= 1;
	}

	return crc;
}

SoftWire::SoftWire(uint8_t sda, uint8_t scl) :
	_sda(sda),
	_scl(scl),
	_inputMode(INPUT), // Pullups diabled by default
	_delay_us(defaultDelay_us),
	_timeout_ms(defaultTimeout_ms),
	_setSdaLow(setSdaLow),
	_setSdaHigh(setSdaHigh),
	_setSclLow(setSclLow),
	_setSclHigh(setSclHigh),
	_readSda(readSda),
	_readScl(readScl)
{
	;
}

void SoftWire::begin(void) const
{
	/*
	// Release SDA and SCL
	_setSdaHigh(this);
	delayMicroseconds(_delay_us);
	_setSclHigh(this);
	*/
	stop();
}

void SoftWire::stop(void) const
{
	// Force SCL low
	_setSclLow(this);
	delayMicroseconds(_delay_us);

	// Force SDA low
	_setSdaLow(this);
	delayMicroseconds(_delay_us);

	// Release SCL
	_setSclHigh(this);
	delayMicroseconds(_delay_us);

	// Release SDA
	_setSdaHigh(this);
	delayMicroseconds(_delay_us);
}

SoftWire::result_t SoftWire::llStart(uint8_t rawAddr) const
{

	// Force SDA low
	_setSdaLow(this);
	delayMicroseconds(_delay_us);

	// Force SCL low
	_setSclLow(this);
	delayMicroseconds(_delay_us);
	return write(rawAddr);
}

SoftWire::result_t SoftWire::llRepeatedStart(uint8_t rawAddr) const
{
	// Force SCL low
	_setSclLow(this);
	delayMicroseconds(_delay_us);

	// Release SDA
	_setSdaHigh(this);
	delayMicroseconds(_delay_us);

	// Release SCL
	_setSclHigh(this);
	delayMicroseconds(_delay_us);

	// Force SDA low
	_setSdaLow(this);
	delayMicroseconds(_delay_us);

	return write(rawAddr);
}

SoftWire::result_t SoftWire::llStartWait(uint8_t rawAddr) const
{
	AsyncDelay timeout(_timeout_ms, AsyncDelay::MILLIS);

	while (!timeout.isExpired()) {
		// Force SDA low
		_setSdaLow(this);
		delayMicroseconds(_delay_us);

		switch (write(rawAddr)) {
		case ack:
			return ack;
		case nack:
			stop();
		default:
			// timeout, and anything else we don't know about
			stop();
			return timedOut;
		}
	}
	return timedOut;
}

SoftWire::result_t SoftWire::write(uint8_t data) const
{
	AsyncDelay timeout(_timeout_ms, AsyncDelay::MILLIS);
	for (uint8_t i = 8; i; --i) {
		// Force SCL low
		_setSclLow(this);

		if (data & 0x80) {
			// Release SDA
			_setSdaHigh(this);
		}
		else {
			// Force SDA low
			_setSdaLow(this);
		}
		delayMicroseconds(_delay_us);

		// Release SCL
		_setSclHigh(this);

		delayMicroseconds(_delay_us);

		data <<= 1;
		if (timeout.isExpired()) {
			stop(); // Reset bus
			return timedOut;
		}
	}

	// Get ACK
	// Force SCL low
	_setSclLow(this);

	// Release SDA
	_setSdaHigh(this);

	delayMicroseconds(_delay_us);

	// Release SCL
	_setSclHigh(this);

	// Wait for SCL to be set high (in case wait states are inserted)
	while (_readScl(this) == LOW)
		if (timeout.isExpired()) {
			stop(); // Reset bus
			return timedOut;
		}

	result_t res = (_readSda(this) == LOW ? ack : nack);

	delayMicroseconds(_delay_us);

	// Keep SCL low between bytes
	_setSclLow(this);

	return res;
}

SoftWire::result_t SoftWire::read(uint8_t &data, bool sendAck) const
{
	data = 0;
	AsyncDelay timeout(_timeout_ms, AsyncDelay::MILLIS);

	for (uint8_t i = 8; i; --i) {
		data <<= 1;

		// Force SCL low
		_setSclLow(this);

		// Release SDA (from previous ACK)
		_setSdaHigh(this);
		delayMicroseconds(_delay_us);

		// Release SCL
		_setSclHigh(this);
		delayMicroseconds(_delay_us);

		// Read clock stretch
		while (_readScl(this) == LOW)
			if (timeout.isExpired()) {
				stop(); // Reset bus
				return timedOut;
			}

		if (_readSda(this))
			data |= 1;
	}

	// Put ACK/NACK

	// Force SCL low
	_setSclLow(this);
	if (sendAck) {
		// Force SDA low
		_setSdaLow(this);
	}
	else {
		// Release SDA
		_setSdaHigh(this);
	}

	delayMicroseconds(_delay_us);

	// Release SCL
	_setSclHigh(this);
	delayMicroseconds(_delay_us);

	// Wait for SCL to return high
	while (_readScl(this) == LOW)
		if (timeout.isExpired()) {
			stop(); // Reset bus
			return timedOut;
		}

	delayMicroseconds(_delay_us);

	// Keep SCL low between bytes
	_setSclLow(this);

	return ack;
}
<commit_msg>Extend support for non-AVR architectures<commit_after>// If possible disable interrupts whilst switching pin direction. Sadly
// there is no generic Arduino function to read the current interrupt
// status, only to enable and disable interrupts.  As a result the
// protection against spurious signals on the I2C bus is only available
// for AVR architectures where ATOMIC_BLOCK is defined.

#if defined(ARDUINO_ARCH_AVR)
#include <util/atomic.h>
#endif

#include <SoftWire.h>
#include <AsyncDelay.h>

// Force SDA low
void SoftWire::setSdaLow(const SoftWire *p)
{
	uint8_t sda = p->getSda();

#ifdef ATOMIC_BLOCK
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
#endif
	{
		digitalWrite(sda, LOW);
		pinMode(sda, OUTPUT);
	}
}

// Release SDA to float high
void SoftWire::setSdaHigh(const SoftWire *p)
{
	pinMode(p->getSda(), p->getInputMode());
}

// Force SCL low
void SoftWire::setSclLow(const SoftWire *p)
{
	uint8_t scl = p->getScl();

#ifdef ATOMIC_BLOCK
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
#endif
	{
		digitalWrite(scl, LOW);
		pinMode(scl, OUTPUT);
	}
}

// Release SCL to float high
void SoftWire::setSclHigh(const SoftWire *p)
{
	pinMode(p->getScl(), p->getInputMode());
}

// Read SDA (for data read)
uint8_t SoftWire::readSda(const SoftWire *p)
{
	return digitalRead(p->getSda());
}

// Read SCL (to detect clock-stretching)
uint8_t SoftWire::readScl(const SoftWire *p)
{
	return digitalRead(p->getScl());
}

// For testing the CRC-8 calculator may be useful:
// http://smbus.org/faq/crc8Applet.htm
uint8_t SoftWire::crc8_update(uint8_t crc, uint8_t data)
{
	const uint16_t polynomial = 0x107;
	crc ^= data;
	for (uint8_t i = 8; i; --i) {
		if (crc & 0x80)
			crc = (uint16_t(crc) << 1) ^ polynomial;
		else
			crc <<= 1;
	}

	return crc;
}

SoftWire::SoftWire(uint8_t sda, uint8_t scl) :
	_sda(sda),
	_scl(scl),
	_inputMode(INPUT), // Pullups diabled by default
	_delay_us(defaultDelay_us),
	_timeout_ms(defaultTimeout_ms),
	_setSdaLow(setSdaLow),
	_setSdaHigh(setSdaHigh),
	_setSclLow(setSclLow),
	_setSclHigh(setSclHigh),
	_readSda(readSda),
	_readScl(readScl)
{
	;
}

void SoftWire::begin(void) const
{
	/*
	// Release SDA and SCL
	_setSdaHigh(this);
	delayMicroseconds(_delay_us);
	_setSclHigh(this);
	*/
	stop();
}

void SoftWire::stop(void) const
{
	// Force SCL low
	_setSclLow(this);
	delayMicroseconds(_delay_us);

	// Force SDA low
	_setSdaLow(this);
	delayMicroseconds(_delay_us);

	// Release SCL
	_setSclHigh(this);
	delayMicroseconds(_delay_us);

	// Release SDA
	_setSdaHigh(this);
	delayMicroseconds(_delay_us);
}

SoftWire::result_t SoftWire::llStart(uint8_t rawAddr) const
{

	// Force SDA low
	_setSdaLow(this);
	delayMicroseconds(_delay_us);

	// Force SCL low
	_setSclLow(this);
	delayMicroseconds(_delay_us);
	return write(rawAddr);
}

SoftWire::result_t SoftWire::llRepeatedStart(uint8_t rawAddr) const
{
	// Force SCL low
	_setSclLow(this);
	delayMicroseconds(_delay_us);

	// Release SDA
	_setSdaHigh(this);
	delayMicroseconds(_delay_us);

	// Release SCL
	_setSclHigh(this);
	delayMicroseconds(_delay_us);

	// Force SDA low
	_setSdaLow(this);
	delayMicroseconds(_delay_us);

	return write(rawAddr);
}

SoftWire::result_t SoftWire::llStartWait(uint8_t rawAddr) const
{
	AsyncDelay timeout(_timeout_ms, AsyncDelay::MILLIS);

	while (!timeout.isExpired()) {
		// Force SDA low
		_setSdaLow(this);
		delayMicroseconds(_delay_us);

		switch (write(rawAddr)) {
		case ack:
			return ack;
		case nack:
			stop();
		default:
			// timeout, and anything else we don't know about
			stop();
			return timedOut;
		}
	}
	return timedOut;
}

SoftWire::result_t SoftWire::write(uint8_t data) const
{
	AsyncDelay timeout(_timeout_ms, AsyncDelay::MILLIS);
	for (uint8_t i = 8; i; --i) {
		// Force SCL low
		_setSclLow(this);

		if (data & 0x80) {
			// Release SDA
			_setSdaHigh(this);
		}
		else {
			// Force SDA low
			_setSdaLow(this);
		}
		delayMicroseconds(_delay_us);

		// Release SCL
		_setSclHigh(this);

		delayMicroseconds(_delay_us);

		data <<= 1;
		if (timeout.isExpired()) {
			stop(); // Reset bus
			return timedOut;
		}
	}

	// Get ACK
	// Force SCL low
	_setSclLow(this);

	// Release SDA
	_setSdaHigh(this);

	delayMicroseconds(_delay_us);

	// Release SCL
	_setSclHigh(this);

	// Wait for SCL to be set high (in case wait states are inserted)
	while (_readScl(this) == LOW)
		if (timeout.isExpired()) {
			stop(); // Reset bus
			return timedOut;
		}

	result_t res = (_readSda(this) == LOW ? ack : nack);

	delayMicroseconds(_delay_us);

	// Keep SCL low between bytes
	_setSclLow(this);

	return res;
}

SoftWire::result_t SoftWire::read(uint8_t &data, bool sendAck) const
{
	data = 0;
	AsyncDelay timeout(_timeout_ms, AsyncDelay::MILLIS);

	for (uint8_t i = 8; i; --i) {
		data <<= 1;

		// Force SCL low
		_setSclLow(this);

		// Release SDA (from previous ACK)
		_setSdaHigh(this);
		delayMicroseconds(_delay_us);

		// Release SCL
		_setSclHigh(this);
		delayMicroseconds(_delay_us);

		// Read clock stretch
		while (_readScl(this) == LOW)
			if (timeout.isExpired()) {
				stop(); // Reset bus
				return timedOut;
			}

		if (_readSda(this))
			data |= 1;
	}

	// Put ACK/NACK

	// Force SCL low
	_setSclLow(this);
	if (sendAck) {
		// Force SDA low
		_setSdaLow(this);
	}
	else {
		// Release SDA
		_setSdaHigh(this);
	}

	delayMicroseconds(_delay_us);

	// Release SCL
	_setSclHigh(this);
	delayMicroseconds(_delay_us);

	// Wait for SCL to return high
	while (_readScl(this) == LOW)
		if (timeout.isExpired()) {
			stop(); // Reset bus
			return timedOut;
		}

	delayMicroseconds(_delay_us);

	// Keep SCL low between bytes
	_setSclLow(this);

	return ack;
}
<|endoftext|>


<commit_before>#include "led_matrix.h"
#include "lsp25h.h"
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <chrono>
#include <thread>
#include <iostream>
#include <iomanip>

int main(void)
{
    using Clock = std::chrono::high_resolution_clock;
    using Duration = Clock::duration;

    const Duration dt = std::chrono::milliseconds(100);

    Lsp25h lsp25h;
    LedMatrix led_matrix;

    const time_t start_t = time(NULL);
    double pressure_zero = 0;
    double altitude_zero = 0;

    while (1) {
        auto start = Clock::now();

        double pressure = lsp25h.read_pressure();
        double temp = lsp25h.read_temp();

        // US Standard Atmosphere formula, see section 6.4 of the LSP25H app note
        double altitude = (1.0 - pow(pressure/1013.25, 0.190284))*145366.45/3.280839895;
        altitude = std::max(0.0, altitude - altitude_zero);

        // Hypsometric equation: https://en.wikipedia.org/wiki/Hypsometric_equation
        double altitude_hypso = log(pressure_zero / pressure) * 8.3144621 * (temp + 273.15) / (9.80665 * 0.028965338);

        std::cout << std::fixed << "P = " << std::setprecision(2) << pressure << " hPa; "
            << "T = " << std::setprecision(1) << temp << " \u00B0C; "
            << "Alt(P) = " << std::setprecision(1) << altitude << " m; "
            << "Alt(P, T) = " << std::setprecision(1) << altitude_hypso << " m" << std::endl;

        // show current level on the led screen
        led_matrix.set(0, 0, 0);
        const size_t n = std::min<size_t>(std::round(altitude/2.0*LedMatrix::Height), LedMatrix::Height);
        for (size_t x = 0; x < LedMatrix::Width; x++) {
            for (size_t y = 0; y < n; y++) {
                led_matrix.set(x, y, std::rand() % 255, std::rand() % 255, std::rand() % 255);
            }
        }

        // set offset to current value after a few seconds
        if (altitude_zero == 0 && time(NULL) - start_t > 5)
        {
            pressure_zero = pressure;
            altitude_zero = altitude;
            std::cout << "Pressure of reference = " << pressure_zero <<
                ", altitude of reference = " << altitude_zero << std::endl;;
        }

        auto stop = Clock::now();
        auto remaining = dt - (stop - start);

        if (remaining >= Duration(0)) {
            std::this_thread::sleep_for(remaining);
        } else {
            std::cerr << "OVERRUN!" << std::endl;
        }
    }

    return 0;
}
<commit_msg>Fix altitude zeroing<commit_after>#include "led_matrix.h"
#include "lsp25h.h"
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <chrono>
#include <thread>
#include <iostream>
#include <iomanip>
#include <limits>
#include <cmath>

int main(void)
{
    using Clock = std::chrono::high_resolution_clock;
    using Duration = Clock::duration;

    const Duration dt = std::chrono::milliseconds(100);

    Lsp25h lsp25h;
    LedMatrix led_matrix;

    const time_t start_t = time(NULL);
    double pressure_zero = std::numeric_limits<double>::infinity();
    double altitude_zero = std::numeric_limits<double>::infinity();

    while (1) {
        auto start = Clock::now();

        double pressure = lsp25h.read_pressure();
        double temp = lsp25h.read_temp();

        // US Standard Atmosphere formula, see section 6.4 of the LSP25H app note
        double altitude = (1.0 - pow(pressure/1013.25, 0.190284))*145366.45/3.280839895;

        if (std::isfinite(altitude_zero)) {
            altitude = std::max(0.0, altitude - altitude_zero);
        }

        // Hypsometric equation: https://en.wikipedia.org/wiki/Hypsometric_equation
        double altitude_hypso = log(pressure_zero / pressure) * 8.3144621 * (temp + 273.15) / (9.80665 * 0.028965338);

        std::cout << std::fixed << "P = " << std::setprecision(2) << pressure << " hPa; "
            << "T = " << std::setprecision(1) << temp << " \u00B0C; "
            << "Alt(P) = " << std::setprecision(1) << altitude << " m; "
            << "Alt(P, T) = " << std::setprecision(1) << altitude_hypso << " m" << std::endl;

        // show current level on the led screen
        led_matrix.set(0, 0, 0);
        const size_t n = std::min<size_t>(std::round(altitude/2.0*LedMatrix::Height), LedMatrix::Height);
        for (size_t x = 0; x < LedMatrix::Width; x++) {
            for (size_t y = 0; y < n; y++) {
                led_matrix.set(x, y, 255, 0, 0);
            }
        }

        // set offset to current value after a few seconds
        if (std::isinf(altitude_zero) && std::isinf(pressure_zero) && time(NULL) - start_t > 5) {
            pressure_zero = pressure;
            altitude_zero = altitude;
            std::cout << "Pressure of reference = " << pressure_zero <<
                ", altitude of reference = " << altitude_zero << std::endl;;
        }

        auto stop = Clock::now();
        auto remaining = dt - (stop - start);

        if (remaining >= Duration(0)) {
            std::this_thread::sleep_for(remaining);
        } else {
            std::cerr << "OVERRUN!" << std::endl;
        }
    }

    return 0;
}
<|endoftext|>


<commit_before>// RUN: clang -cc1 -O1 -emit-llvm %s -o - | FileCheck %s

// Check that the following construct, which is similar to one which occurs
// in Firefox, is not misfolded (folding it correctly would be a bonus, but
// that doesn't work at the moment, hence the -O1 in the runline).
struct A { char x; };
struct B { char y; };
struct C : A,B {};
unsigned char x = ((char*)(B*)(C*)0x1000) - (char*)0x1000;

// CHECK: @x = global i8 1
<commit_msg>Fix runline.<commit_after>// RUN: %clang_cc1 -O1 -emit-llvm %s -o - | FileCheck %s

// Check that the following construct, which is similar to one which occurs
// in Firefox, is not misfolded (folding it correctly would be a bonus, but
// that doesn't work at the moment, hence the -O1 in the runline).
struct A { char x; };
struct B { char y; };
struct C : A,B {};
unsigned char x = ((char*)(B*)(C*)0x1000) - (char*)0x1000;

// CHECK: @x = global i8 1
<|endoftext|>


<commit_before>#include <database.hpp>
#include <error.hpp>
#include <cache.hpp>
#include <challonge.hpp>
#include <algorithm>
#include <iostream>
#include <boost/filesystem.hpp>

namespace opt = gears::optparse;
namespace fs  = boost::filesystem;

namespace hypest {
opt::subcommand database() {
    opt::option_set args = {
        { "rank", 'r', "updates the rating period with the given bracket", opt::value<std::string>("url") },
        { "force", 'f', "force updating despite being the url(s) being processed already" },
        { "commit", 'c', "finalises a rating period and updates player's rankings" },
        { "rebuild", "rebuilds the database with the db.cache file" },
        { "verbose", "verbose output" }
    };

    opt::subcommand result = { "database", "handles the hypest database", args };
    result.description = "Updates, deletes, or otherwise fiddles with the Hypest database that keeps track of matches\n"
                         "\nIn order to add things to the rating period you must use --rank <url> for every bracket."
                         "Once the rating period is seemingly complete, use --commit to finalise the rating period";
    return result;
}

void rebuild_database(const rank_cache& cache, bool verbose) {
    if(fs::exists("rating_period.cache")) {
        std::cerr << "hypest: warning: rating period is currently in place\n";
    }

    // clear the databases
    fs::remove_all("database");

    int rating_period = 1;
    for(auto&& entry : cache) {
        if(entry.rating_period != rating_period) {
            if(verbose) {
                std::cout << "Rating period (" << rating_period << ") has completed\n";
            }
            commit();
            ++rating_period;
        }
        if(verbose) {
            std::cout << "Processing " << entry.url << '\n';
        }
        rank(entry.url);
    }
    if(cache.current_rating_period < rating_period) {
        if(verbose) {
            std::cout << "Rating period (" << rating_period << ") has completed\n";
        }
        commit();
    }
}

void database(const opt::arguments& args) {
    auto&& opts = args.options;
    rank_cache cache = get_cache();
    bool forced = opts.is_active("force");
    bool verbose = opts.is_active("verbose");
    if(opts.is_active("rank")) {
        auto&& url = opts.get<std::string>("rank");
        if(not forced) {
            if(cache.in(url)) {
                auto notes = {
                    "use --force to reprocess"
                };
                throw noted_error("bracket has already been processed", notes);
            }
            cache.add(url);
        }
        if(verbose) {
            std::cout << "Processing " << url << '\n';
        }
        rank(url);
    }

    if(opts.is_active("rebuild")) {
        // sort database by rating period
        std::sort(std::begin(cache), std::end(cache), [](const auto& lhs, const auto& rhs) {
            return lhs.rating_period < rhs.rating_period;
        });
        rebuild_database(cache, verbose);
        return;
    }

    if(opts.is_active("commit")) {
        commit();
    }

    if(not forced) {
        if(opts.is_active("commit")) {
            ++cache.current_rating_period;
        }
        if(verbose) {
            std::cout << "Updating cache...\n";
        }
        update_cache(cache);
    }
}
} // hypest
<commit_msg>Add dump command to dump JSON to stdout.<commit_after>#include <database.hpp>
#include <error.hpp>
#include <config.hpp>
#include <cache.hpp>
#include <challonge.hpp>
#include <algorithm>
#include <iostream>
#include <boost/filesystem.hpp>

namespace opt = gears::optparse;
namespace fs  = boost::filesystem;

namespace hypest {
opt::subcommand database() {
    opt::option_set args = {
        { "rank", 'r', "updates the rating period with the given bracket", opt::value<std::string>("url") },
        { "force", 'f', "force updating despite being the url(s) being processed already" },
        { "commit", 'c', "finalises a rating period and updates player's rankings" },
        { "rebuild", "rebuilds the database with the db.cache file" },
        { "verbose", "verbose output" },
        { "dump", "dumps the tournament response JSON to stdout and exits", opt::value<std::string>("url") }
    };

    opt::subcommand result = { "database", "handles the hypest database", args };
    result.description = "Updates, deletes, or otherwise fiddles with the Hypest database that keeps track of matches\n"
                         "\nIn order to add things to the rating period you must use --rank <url> for every bracket."
                         "Once the rating period is seemingly complete, use --commit to finalise the rating period";
    return result;
}

void rebuild_database(const rank_cache& cache, bool verbose) {
    if(fs::exists("rating_period.cache")) {
        std::cerr << "hypest: warning: rating period is currently in place\n";
    }

    // clear the databases
    fs::remove_all("database");

    int rating_period = 1;
    for(auto&& entry : cache) {
        if(entry.rating_period != rating_period) {
            if(verbose) {
                std::cout << "Rating period (" << rating_period << ") has completed\n";
            }
            commit();
            ++rating_period;
        }
        if(verbose) {
            std::cout << "Processing " << entry.url << '\n';
        }
        rank(entry.url);
    }
    if(cache.current_rating_period < rating_period) {
        if(verbose) {
            std::cout << "Rating period (" << rating_period << ") has completed\n";
        }
        commit();
    }
}

void database(const opt::arguments& args) {
    auto&& opts = args.options;
    rank_cache cache = get_cache();
    bool forced = opts.is_active("force");
    bool verbose = opts.is_active("verbose");

    if(opts.is_active("dump")) {
        auto tournament = get_tournament(get_config(), opts.get<std::string>("dump"));
        json::dump(std::cout, tournament);
        return;
    }

    if(opts.is_active("rank")) {
        auto&& url = opts.get<std::string>("rank");
        if(not forced) {
            if(cache.in(url)) {
                auto notes = {
                    "use --force to reprocess"
                };
                throw noted_error("bracket has already been processed", notes);
            }
            cache.add(url);
        }
        if(verbose) {
            std::cout << "Processing " << url << '\n';
        }
        rank(url);
    }

    if(opts.is_active("rebuild")) {
        // sort database by rating period
        std::sort(std::begin(cache), std::end(cache), [](const auto& lhs, const auto& rhs) {
            return lhs.rating_period < rhs.rating_period;
        });
        rebuild_database(cache, verbose);
        return;
    }

    if(opts.is_active("commit")) {
        commit();
    }

    if(not forced) {
        if(opts.is_active("commit")) {
            ++cache.current_rating_period;
        }
        if(verbose) {
            std::cout << "Updating cache...\n";
        }
        update_cache(cache);
    }
}
} // hypest
<|endoftext|>


<commit_before>/**
* Dynamically Loaded Object
* (C) 2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/internal/dyn_load.h>
#include <botan/build.h>
#include <stdexcept>

#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
  #include <dlfcn.h>
#endif

namespace Botan {

Dynamically_Loaded_Library::Dynamically_Loaded_Library(
   const std::string& library) :
   lib_name(library), lib(0)
   {
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
   lib = ::dlopen(lib_name.c_str(), RTLD_LAZY);

   if(!lib)
      throw std::runtime_error("Failed to load engine " + lib_name);
#endif

   }

Dynamically_Loaded_Library::~Dynamically_Loaded_Library()
   {
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
   ::dlclose(lib);
#endif
   }

void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol)
   {
   void* addr = 0;

#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
   addr = ::dlsym(lib, symbol.c_str());
#endif

   if(!addr)
      throw std::runtime_error("Failed to resolve symbol " + symbol +
                               " in " + lib_name);

   return addr;
   }

}
<commit_msg>If dynamic loading fails, include result of dlerror() in the exception msg<commit_after>/**
* Dynamically Loaded Object
* (C) 2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/internal/dyn_load.h>
#include <botan/build.h>
#include <stdexcept>

#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
  #include <dlfcn.h>
#endif

namespace Botan {

Dynamically_Loaded_Library::Dynamically_Loaded_Library(
   const std::string& library) :
   lib_name(library), lib(0)
   {
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
   lib = ::dlopen(lib_name.c_str(), RTLD_LAZY);

   if(!lib)
      {
      const char* dl_err = dlerror();
      if(!dl_err)
         dl_err = "Unknown error";

      throw std::runtime_error("Failed to load engine " + lib_name + ": " +
                               dl_err);
      }
#endif

   }

Dynamically_Loaded_Library::~Dynamically_Loaded_Library()
   {
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
   ::dlclose(lib);
#endif
   }

void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol)
   {
   void* addr = 0;

#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
   addr = ::dlsym(lib, symbol.c_str());
#endif

   if(!addr)
      throw std::runtime_error("Failed to resolve symbol " + symbol +
                               " in " + lib_name);

   return addr;
   }

}
<|endoftext|>


<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2017 Ryo Suzuki
//	Copyright (c) 2016-2017 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# pragma once
# include "Fwd.hpp"
# include "String.hpp"
# include "StringView.hpp"

# define EMOJIDEF(NAME,CH) static constexpr Helper NAME = { CH };

namespace s3d
{
	struct Emoji
	{
	private:

		struct Helper
		{
			const wchar_t* codePoints;
		};

	public:

		String codePoints;

		explicit Emoji(StringView emoji) noexcept
			: codePoints(emoji) {}

		Emoji(Helper helper) noexcept
			: codePoints(helper.codePoints) {}

		static Image LoadImage(StringView emoji);

		static Image LoadSilhouette(StringView emoji);

		//
		// https://www.google.com/get/noto/help/emoji/
		//

		/// <summary>
		/// 🔥
		/// </summary>
		EMOJIDEF(Fire, L"🔥");

		/// <summary>
		/// ⚽
		/// </summary>
		EMOJIDEF(SoccerBall, L"⚽");

		/// <summary>
		/// 🐵
		/// </summary>
		EMOJIDEF(MonkeyFace, L"🐵");

		/// <summary>
		/// 🍔
		/// </summary>
		EMOJIDEF(Hamburger, L"🍔");
	};
}

# undef U32WIDEN
# undef EMOJIDEF
<commit_msg>update Emoji<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2017 Ryo Suzuki
//	Copyright (c) 2016-2017 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# pragma once
# include "Fwd.hpp"
# include "String.hpp"
# include "StringView.hpp"

namespace s3d
{
	//
	// https://github.com/Siv3D/OpenSiv3D/wiki/Emoji-list
	// https://www.google.com/get/noto/help/emoji/
	//
	struct Emoji
	{
		String codePoints;

		explicit Emoji(StringView emoji) noexcept
			: codePoints(emoji) {}

		static Image LoadImage(StringView emoji);

		static Image LoadSilhouette(StringView emoji);
	};
}

<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <string>

using namespace std;

class Rational
{
    int a, b;

    int gcd(int a, int b);
    void simplify();
    bool check(const Rational& f);
public:
    Rational(int a=0, int b=1) : a(a) , b(b) {
        if (b == 0)
            return;
        simplify();
    };

    Rational& operator= (const Rational& f);

    Rational& Add(const Rational& f);
    Rational& Substract(const Rational& f);
    Rational& Multiply(const Rational& f);
    Rational& Divide(const Rational& f);

    bool EqualTo(const Rational& f) const;
    int CompareTo(const Rational& f) const;

    bool IsInteger() const;

    string ToString() const;
};

int Rational::gcd (int a, int b)
{
    int c;
    while (b) {
        c = b;
        b = a % b;
        a = c;
    }
    return a;
}

void Rational::simplify()
{
    int c;
    while ((c = gcd(a, b)) != 1) {
        if (c == 0)
            break;
        a /= c;
        b /= c;
    }
}

bool Rational::check(const Rational& f)
{
    if (b == 0 || f.b == 0) {
        b = 0;
        return true;
    }
    return false;
}

Rational& Rational::operator= (const Rational& f)
{
    if (this != &f) {
        a = f.a;
        b = f.b;
    }
    return *this;
}

Rational& Rational::Add(const Rational& f)
{
    check(f);
    a = a * f.b + b * f.a;
    b = b * f.b;
    simplify();
    return *this;
}

Rational& Rational::Substract(const Rational& f)
{
    check(f);
    a = a * f.b - b * f.a;
    b = b * f.b;
    simplify();
    return *this;
}

Rational& Rational::Multiply(const Rational& f)
{
    check(f);
    a *= f.a;
    b *= f.b;
    simplify();
    return *this;
}

Rational& Rational::Divide(const Rational& f)
{
    check(f);
    a *= f.b;
    b *= f.a;
    simplify();
    return *this;
}

bool Rational::EqualTo(const Rational& f) const
{
    if (f.a == a && f.b == b)
        return true;
    else
        return false;
}

int Rational::CompareTo(const Rational& f) const
{
    int c = a * f.b;
    int d = b * f.a;

    if (c > d)
        return 1;
    if (c < d)
        return -1;
    return 0;
}

bool Rational::IsInteger() const
{
    if (b == 1)
        return true;
    return false;
}

string Rational::ToString() const
{
    stringstream ss;
    if (b == 0) {
        if (a >= 0)
            return "+NAN";
        if (a < 0)
            return "-NAN";
    } else {
        ss << a << "/" << b;
    }
    return ss.str();
}

const Rational a(1,1);

int main()
{
    Rational q  = Rational(1, 3), w(1, 4);
    Rational s = 4;
//    a.CompareTo(s);
    w = q;

    s.Add(q);
    cout << s.ToString() << endl;

    s.Substract(q);
    cout << s.ToString() << endl;

    s.Multiply(q);
    cout << s.ToString() << endl;

    s.Divide(q);
    cout << s.ToString() << endl;

    s.Add(q).Multiply(w);
    cout << s.ToString() << endl;

    s.EqualTo(w);
    s.CompareTo(w);

    s.IsInteger();

    cout << s.ToString() << endl;
//    cout << q.ToString() << endl;
//    cout << w.ToString() << endl;

    return 0;
}

//#include <task.rational.cpp>
<commit_msg>class name changed<commit_after>#include <iostream>
#include <sstream>
#include <string>

using namespace std;

class Rational
{
    int a, b;

    int gcd(int a, int b);
    void simplify();
    bool check(const Rational& f);
public:
    Rational(int a=0, int b=1) : a(a) , b(b) {
        if (b == 0)
            return;
        simplify();
    };

    Rational& operator= (const Rational& f);

    Rational& Add(const Rational& f);
    Rational& Substract(const Rational& f);
    Rational& Multiply(const Rational& f);
    Rational& Divide(const Rational& f);

    bool EqualTo(const Rational& f) const;
    int CompareTo(const Rational& f) const;

    bool IsInteger() const;

    string ToString() const;
};

int Rational::gcd (int a, int b)
{
    int c;
    while (b) {
        c = b;
        b = a % b;
        a = c;
    }
    return a;
}

void Rational::simplify()
{
    int c;
    while ((c = gcd(a, b)) != 1) {
        if (c == 0)
            break;
        a /= c;
        b /= c;
    }
}

bool Rational::check(const Rational& f)
{
    if (b == 0 || f.b == 0) {
        b = 0;
        return true;
    }
    return false;
}

Rational& Rational::operator= (const Rational& f)
{
    if (this != &f) {
        a = f.a;
        b = f.b;
    }
    return *this;
}

Rational& Rational::Add(const Rational& f)
{
    check(f);
    a = a * f.b + b * f.a;
    b = b * f.b;
    simplify();
    return *this;
}

Rational& Rational::Substract(const Rational& f)
{
    check(f);
    a = a * f.b - b * f.a;
    b = b * f.b;
    simplify();
    return *this;
}

Rational& Rational::Multiply(const Rational& f)
{
    check(f);
    a *= f.a;
    b *= f.b;
    simplify();
    return *this;
}

Rational& Rational::Divide(const Rational& f)
{
    check(f);
    a *= f.b;
    b *= f.a;
    simplify();
    return *this;
}

bool Rational::EqualTo(const Rational& f) const
{
    if (f.a == a && f.b == b)
        return true;
    else
        return false;
}

int Rational::CompareTo(const Rational& f) const
{
    int c = a * f.b;
    int d = b * f.a;

    if (c > d)
        return 1;
    if (c < d)
        return -1;
    return 0;
}

bool Rational::IsInteger() const
{
    if (b == 1)
        return true;
    return false;
}

string Rational::ToString() const
{
    stringstream ss;
    if (b == 0) {
        if (a >= 0)
            return "+NAN";
        if (a < 0)
            return "-NAN";
    } else {
        ss << a << "/" << b;
    }
    return ss.str();
}

const Rational a(1,1);

int main()
{
    Rational q  = Rational(1, 3), w(1, 4);
    Rational s = 4;
//    a.CompareTo(s);
    w = q;

    s.Add(q);
    cout << s.ToString() << endl;

    s.Substract(q);
    cout << s.ToString() << endl;

    s.Multiply(q);
    cout << s.ToString() << endl;

    s.Divide(q);
    cout << s.ToString() << endl;

    s.Add(q).Multiply(w);
    cout << s.ToString() << endl;

    s.EqualTo(w);
    s.CompareTo(w);

    s.IsInteger();

    cout << s.ToString() << endl;
//    cout << q.ToString() << endl;
//    cout << w.ToString() << endl;

    return 0;
}

<|endoftext|>


<commit_before>//
// Copyright (c) 2009, Zbigniew Zagorski
// This software licensed under terms described in LICENSE.txt
//

#include "../platform.h"

#ifdef TINFRA_W32

#include "tinfra/fs.h"

#include "tinfra/win32.h"
#include "tinfra/path.h"
#include "tinfra/fmt.h"
#include "tinfra/cmd.h" // for getapp

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

#include "tinfra/trace.h"

namespace tinfra {
namespace fs {

tinfra::module_tracer win32_fs_tracer(tinfra::tinfra_tracer, "win32_fs", 70);

struct lister::internal_data {

    HANDLE ff_handle;
    WIN32_FIND_DATAW ff_data;
    bool         is_first;
    std::string  name_holder;
};

lister::lister(tstring const& path, bool /*need_stat*/)
    : data_(new internal_data())
{
    TINFRA_TRACE(win32_fs_tracer, "lister::lister");
    TINFRA_TRACE_VAR(win32_fs_tracer, path);
    std::wstring wname = tinfra::win32::make_wstring_from_utf8(path);
    wname.append(L"\\*.*");
    data_->ff_handle = FindFirstFileW(wname.c_str(), &data_->ff_data );

    if( data_->ff_handle == INVALID_HANDLE_VALUE ) {
        tinfra::win32::throw_system_error(fmt("unable to list directory '%s'") % path);
    }
    data_->is_first = true;
}
lister::~lister()
{
    TINFRA_TRACE(win32_fs_tracer, "lister::~lister");
    if( data_->ff_handle != INVALID_HANDLE_VALUE )
        FindClose(data_->ff_handle);
}

bool lister::fetch_next(directory_entry& result)
{
    TINFRA_TRACE(win32_fs_tracer, "lister::fetch_next");

    while( true ) {
        bool have_data = data_->is_first;
        data_->is_first = false;
        if( !have_data )
            have_data =  (FindNextFileW(data_->ff_handle, &data_->ff_data) != 0 );
        if( !have_data )
            return false;

        WIN32_FIND_DATAW& ff_data = data_->ff_data;
        if( ff_data.cFileName[0] == '.' )
        {
            if( (ff_data.cFileName[1] == 0) ||
                (ff_data.cFileName[1] == '.' && ff_data.cFileName[2] == 0) )
            {
                continue;
            }
        }

        data_->name_holder = tinfra::win32::make_utf8(ff_data.cFileName);

        result.name = data_->name_holder;
        TINFRA_TRACE_VAR(win32_fs_tracer, result.name);
        result.info.is_dir = (ff_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == FILE_ATTRIBUTE_DIRECTORY;
        result.info.size = size_t(ff_data.nFileSizeLow);
        // TODO: add support for win64 build
        // result.info.size |= (size_t(ff_data.nFileSizeHigh) << 32);

        // TODO, recognize how to use FILETIME and how to convert it into timestamp
        result.info.modification_time = 0;
        result.info.access_time = 0;
        data_->is_first = false;
        return true;
    }
}

file_info stat(tstring const& name)
{
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);

    WIN32_FILE_ATTRIBUTE_DATA file_attrs;

    const BOOL get_result = GetFileAttributesExW(
        w_name.c_str(),
        GetFileExInfoStandard,
        &file_attrs);
    if( get_result == 0) {
        tinfra::win32::throw_system_error(fmt("unable to get file information for '%s' (GetFileAttributesExW)") % name);
    }

    file_info result;
    result.is_dir = (file_attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
    result.modification_time = 0; // TODO: how to convert FILETIME to epoch time
    result.access_time = 0;  // TODO: how to convert FILETIME to epoch time
    result.size = file_attrs.nFileSizeLow;
	result.type = result.is_dir ? DIRECTORY : REGULAR_FILE;
    // TODO: add support for win64 build
    // result.size |= (size_t(file_attrs.nFileSizeHigh) << 32);
    return result;
}

bool exists(tstring const& name)
{
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const DWORD dwResult = GetFileAttributesW(w_name.c_str());

    if( dwResult == INVALID_FILE_ATTRIBUTES )
        return false;
    else
        return true;
}

static bool is_dir_sep(char a)
{
    return    a == '/'
           || a == '\\';
}

bool is_dir(tstring const& name)
{
    size_t len = name.size();

    if( len == 1 && name[0] == '.' )      // current directory
        return true;

    if( len == 1 && is_dir_sep(name[0]) ) // single backslash
        return true;

#ifdef _WIN32
    if( len >= 2 && std::isalpha(name[0]) && name[1] == ':' ) {
        if( len == 2 )
            return true; // A:
        if( len == 3 && is_dir_sep(name[2]) )
            return true; // A:\ and A:/
    }
    // NOTE: win32 stat doesn't accept trailing slash/back
    // slash in folder name
    if( len > 1 && is_dir_sep(name[len-1]) ) {
        tstring tmp(name.data(), len-1);
        return is_dir(tmp);
    }
#endif
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const DWORD dwResult = GetFileAttributesW(w_name.c_str());

    if( dwResult == INVALID_FILE_ATTRIBUTES )
        return false;
    if( (dwResult & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY )
        return true;
    return false;
}

bool is_file(tstring const& name)
{
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const DWORD dwResult = GetFileAttributesW(w_name.c_str());

    if( dwResult == INVALID_FILE_ATTRIBUTES )
        return false;
    if( (dwResult & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY )
        return false;
    return true;
}

void mv(tstring const& src, tstring const& dest)
{
    std::wstring w_src = tinfra::win32::make_wstring_from_utf8(src);
    std::wstring w_dest = tinfra::win32::make_wstring_from_utf8(dest);
    const BOOL result = ::MoveFileExW(
        w_src.c_str(),
        w_dest.c_str(),
        MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);

    if( result == 0) {
        tinfra::win32::throw_system_error(fmt("unable to move file from '%s' to '%s' (MoveFileExW)") % src % dest);
    }
}

void rm(tstring const& name)
{
    // TODO: according to MSDN, we should remove read-only attribute before deletion (?)
    std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
	const BOOL result = ::DeleteFileW(w_name.c_str());
	if( result == 0 ) {
		tinfra::win32::throw_system_error(fmt("unable to remove file '%s' (DeleteFileW)") % name);
	}
}

void rmdir(tstring const& name)
{
    std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const BOOL result = ::RemoveDirectoryW(w_name.c_str());
    if( result == 0 ) {
        tinfra::win32::throw_system_error(fmt("unable to remove folder '%s' (RemoveDirectoryW)") % name);
    }
}

void mkdir(tstring const& name, bool create_parents)
{
    using tinfra::path::dirname;
    std::string parent = dirname(name);
    if( !is_dir(parent) ) {
        if( create_parents )
            mkdir(parent);
        else {
			const std::string message = (fmt("unable to create dir '%s': %s") % name % "parent folder doesn't exist").str();
            throw std::logic_error(message);
		}
    }

    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const BOOL result = ::CreateDirectoryW(w_name.c_str(), NULL);
    if( result == 0 ) {
        tinfra::win32::throw_system_error(fmt("unable to create dir '%s' (CreateDirectoryW)") % name);
    }
}

/*
TODO
   Those are common to all platforms. Maybe rewrite them in future
   using WinAPI.
*/
/*
void recursive_copy(tstring const& src, tstring const& dest)
{
    tinfra::vfs& fs = tinfra::local_fs();
    tinfra::default_recursive_copy(fs, src, fs, dest);
}

void recursive_rm(tstring const& name)
{
    tinfra::vfs& fs = tinfra::local_fs();
    return tinfra::default_recursive_rm(fs, name);
}

void copy(tstring const& src, tstring const& dest)
{
    tinfra::vfs& fs = tinfra::local_fs();
    return tinfra::default_copy(fs, src, fs, dest);
}
*/

void cd(tstring const& name)
{
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const BOOL result = ::SetCurrentDirectoryW(w_name.c_str());
    if( result == 0 ) {
        tinfra::win32::throw_system_error(fmt("unable to change current directory to '%s' (SetCurrentDirectoryW)") % name);
    }
}

std::string pwd()
{
    const int BUFFER_LEN=2048;
    WCHAR buf[BUFFER_LEN];
    DWORD size = ::GetCurrentDirectoryW(BUFFER_LEN, buf);
    if( size == 0 ) {
        tinfra::win32::throw_system_error("unable to get current directory (GetCurrentDirectoryW)");
    }
    if( size < BUFFER_LEN )  {
        std::wstring w_result(buf, size);
        std::string result = tinfra::win32::make_utf8(w_result.c_str());
        return result;
    }
    tinfra::win32::throw_system_error("fs::pwd() failed (GetCurrentDirectoryW): implement it better!");
    return ""; // just to satisfy compiler
}

//void         symlink(tstring const& target, tstring const& path)
//{
//}

//std::string readlink(tstring const& path)
//{
//
//}

std::string realpath(tstring const& path)
{
    return path;
}

} } // end namespace tinfra::fs

#endif // TINFRA_W32

<commit_msg>w32 fs::lister now correctly fills directory_entry.info.type field<commit_after>//
// Copyright (c) 2009, Zbigniew Zagorski
// This software licensed under terms described in LICENSE.txt
//

#include "../platform.h"

#ifdef TINFRA_W32

#include "tinfra/fs.h"

#include "tinfra/win32.h"
#include "tinfra/path.h"
#include "tinfra/fmt.h"
#include "tinfra/cmd.h" // for getapp

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

#include "tinfra/trace.h"

namespace tinfra {
namespace fs {

tinfra::module_tracer win32_fs_tracer(tinfra::tinfra_tracer, "win32_fs", 70);

struct lister::internal_data {

    HANDLE ff_handle;
    WIN32_FIND_DATAW ff_data;
    bool         is_first;
    std::string  name_holder;
};

lister::lister(tstring const& path, bool /*need_stat*/)
    : data_(new internal_data())
{
    TINFRA_TRACE(win32_fs_tracer, "lister::lister");
    TINFRA_TRACE_VAR(win32_fs_tracer, path);
    std::wstring wname = tinfra::win32::make_wstring_from_utf8(path);
    wname.append(L"\\*.*");
    data_->ff_handle = FindFirstFileW(wname.c_str(), &data_->ff_data );

    if( data_->ff_handle == INVALID_HANDLE_VALUE ) {
        tinfra::win32::throw_system_error(fmt("unable to list directory '%s'") % path);
    }
    data_->is_first = true;
}
lister::~lister()
{
    TINFRA_TRACE(win32_fs_tracer, "lister::~lister");
    if( data_->ff_handle != INVALID_HANDLE_VALUE )
        FindClose(data_->ff_handle);
}

bool lister::fetch_next(directory_entry& result)
{
    TINFRA_TRACE(win32_fs_tracer, "lister::fetch_next");

    while( true ) {
        bool have_data = data_->is_first;
        data_->is_first = false;
        if( !have_data )
            have_data =  (FindNextFileW(data_->ff_handle, &data_->ff_data) != 0 );
        if( !have_data )
            return false;

        WIN32_FIND_DATAW& ff_data = data_->ff_data;
        if( ff_data.cFileName[0] == '.' )
        {
            if( (ff_data.cFileName[1] == 0) ||
                (ff_data.cFileName[1] == '.' && ff_data.cFileName[2] == 0) )
            {
                continue;
            }
        }

        data_->name_holder = tinfra::win32::make_utf8(ff_data.cFileName);

        result.name = data_->name_holder;
        TINFRA_TRACE_VAR(win32_fs_tracer, result.name);
        result.info.is_dir = (ff_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == FILE_ATTRIBUTE_DIRECTORY;
        result.info.type = result.info.is_dir ? DIRECTORY : REGULAR_FILE;
        result.info.size = size_t(ff_data.nFileSizeLow);
        // TODO: add support for win64 build
        // result.info.size |= (size_t(ff_data.nFileSizeHigh) << 32);

        // TODO, recognize how to use FILETIME and how to convert it into timestamp
        result.info.modification_time = 0;
        result.info.access_time = 0;
        data_->is_first = false;
        return true;
    }
}

file_info stat(tstring const& name)
{
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);

    WIN32_FILE_ATTRIBUTE_DATA file_attrs;

    const BOOL get_result = GetFileAttributesExW(
        w_name.c_str(),
        GetFileExInfoStandard,
        &file_attrs);
    if( get_result == 0) {
        tinfra::win32::throw_system_error(fmt("unable to get file information for '%s' (GetFileAttributesExW)") % name);
    }

    file_info result;
    result.is_dir = (file_attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
    result.modification_time = 0; // TODO: how to convert FILETIME to epoch time
    result.access_time = 0;  // TODO: how to convert FILETIME to epoch time
    result.size = file_attrs.nFileSizeLow;
	result.type = result.is_dir ? DIRECTORY : REGULAR_FILE;
    // TODO: add support for win64 build
    // result.size |= (size_t(file_attrs.nFileSizeHigh) << 32);
    return result;
}

bool exists(tstring const& name)
{
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const DWORD dwResult = GetFileAttributesW(w_name.c_str());

    if( dwResult == INVALID_FILE_ATTRIBUTES )
        return false;
    else
        return true;
}

static bool is_dir_sep(char a)
{
    return    a == '/'
           || a == '\\';
}

bool is_dir(tstring const& name)
{
    size_t len = name.size();

    if( len == 1 && name[0] == '.' )      // current directory
        return true;

    if( len == 1 && is_dir_sep(name[0]) ) // single backslash
        return true;

#ifdef _WIN32
    if( len >= 2 && std::isalpha(name[0]) && name[1] == ':' ) {
        if( len == 2 )
            return true; // A:
        if( len == 3 && is_dir_sep(name[2]) )
            return true; // A:\ and A:/
    }
    // NOTE: win32 stat doesn't accept trailing slash/back
    // slash in folder name
    if( len > 1 && is_dir_sep(name[len-1]) ) {
        tstring tmp(name.data(), len-1);
        return is_dir(tmp);
    }
#endif
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const DWORD dwResult = GetFileAttributesW(w_name.c_str());

    if( dwResult == INVALID_FILE_ATTRIBUTES )
        return false;
    if( (dwResult & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY )
        return true;
    return false;
}

bool is_file(tstring const& name)
{
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const DWORD dwResult = GetFileAttributesW(w_name.c_str());

    if( dwResult == INVALID_FILE_ATTRIBUTES )
        return false;
    if( (dwResult & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY )
        return false;
    return true;
}

void mv(tstring const& src, tstring const& dest)
{
    std::wstring w_src = tinfra::win32::make_wstring_from_utf8(src);
    std::wstring w_dest = tinfra::win32::make_wstring_from_utf8(dest);
    const BOOL result = ::MoveFileExW(
        w_src.c_str(),
        w_dest.c_str(),
        MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);

    if( result == 0) {
        tinfra::win32::throw_system_error(fmt("unable to move file from '%s' to '%s' (MoveFileExW)") % src % dest);
    }
}

void rm(tstring const& name)
{
    // TODO: according to MSDN, we should remove read-only attribute before deletion (?)
    std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
	const BOOL result = ::DeleteFileW(w_name.c_str());
	if( result == 0 ) {
		tinfra::win32::throw_system_error(fmt("unable to remove file '%s' (DeleteFileW)") % name);
	}
}

void rmdir(tstring const& name)
{
    std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const BOOL result = ::RemoveDirectoryW(w_name.c_str());
    if( result == 0 ) {
        tinfra::win32::throw_system_error(fmt("unable to remove folder '%s' (RemoveDirectoryW)") % name);
    }
}

void mkdir(tstring const& name, bool create_parents)
{
    using tinfra::path::dirname;
    std::string parent = dirname(name);
    if( !is_dir(parent) ) {
        if( create_parents )
            mkdir(parent);
        else {
			const std::string message = (fmt("unable to create dir '%s': %s") % name % "parent folder doesn't exist").str();
            throw std::logic_error(message);
		}
    }

    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const BOOL result = ::CreateDirectoryW(w_name.c_str(), NULL);
    if( result == 0 ) {
        tinfra::win32::throw_system_error(fmt("unable to create dir '%s' (CreateDirectoryW)") % name);
    }
}

/*
TODO
   Those are common to all platforms. Maybe rewrite them in future
   using WinAPI.
*/
/*
void recursive_copy(tstring const& src, tstring const& dest)
{
    tinfra::vfs& fs = tinfra::local_fs();
    tinfra::default_recursive_copy(fs, src, fs, dest);
}

void recursive_rm(tstring const& name)
{
    tinfra::vfs& fs = tinfra::local_fs();
    return tinfra::default_recursive_rm(fs, name);
}

void copy(tstring const& src, tstring const& dest)
{
    tinfra::vfs& fs = tinfra::local_fs();
    return tinfra::default_copy(fs, src, fs, dest);
}
*/

void cd(tstring const& name)
{
    const std::wstring w_name = tinfra::win32::make_wstring_from_utf8(name);
    const BOOL result = ::SetCurrentDirectoryW(w_name.c_str());
    if( result == 0 ) {
        tinfra::win32::throw_system_error(fmt("unable to change current directory to '%s' (SetCurrentDirectoryW)") % name);
    }
}

std::string pwd()
{
    const int BUFFER_LEN=2048;
    WCHAR buf[BUFFER_LEN];
    DWORD size = ::GetCurrentDirectoryW(BUFFER_LEN, buf);
    if( size == 0 ) {
        tinfra::win32::throw_system_error("unable to get current directory (GetCurrentDirectoryW)");
    }
    if( size < BUFFER_LEN )  {
        std::wstring w_result(buf, size);
        std::string result = tinfra::win32::make_utf8(w_result.c_str());
        return result;
    }
    tinfra::win32::throw_system_error("fs::pwd() failed (GetCurrentDirectoryW): implement it better!");
    return ""; // just to satisfy compiler
}

//void         symlink(tstring const& target, tstring const& path)
//{
//}

//std::string readlink(tstring const& path)
//{
//
//}

std::string realpath(tstring const& path)
{
    return path;
}

} } // end namespace tinfra::fs

#endif // TINFRA_W32

<|endoftext|>


<commit_before>// Copyright (c) 2012, Steinwurf ApS
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Steinwurf ApS nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL Steinwurf ApS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// #include <gtest/gtest.h>
// #include <sak/aligned_allocator.hpp>
// #include <sak/is_aligned.hpp>

// TEST(TestAlignedAllocator, construct)
// {
//     sak::aligned_allocator<uint8_t> alloc;
//     EXPECT_EQ(alloc.alignment(), sak::platform::simd_align);
// }
//
//
// TEST(TestAlignedAllocator, vector)
// {
//     typedef std::vector<uint32_t, sak::aligned_allocator<uint32_t> >
//     aligned_vector;
//
//     aligned_vector v;
//
//     v.push_back(42);
//     v.push_back(56);
//     v.push_back(11);
//
//     EXPECT_TRUE(sak::is_aligned(&v[0]));
//
//     v.push_back(42);
//     v.push_back(56);
//     v.push_back(11);
//
//     EXPECT_TRUE(sak::is_aligned(&v[0]));
//
//     v.push_back(42);
//     v.push_back(56);
//     v.push_back(11);
//
//     EXPECT_TRUE(sak::is_aligned(&v[0]));
//
//     aligned_vector v2 = v;
//
//     EXPECT_TRUE(sak::is_aligned(&v2[0]));
//
//     v2.push_back(42);
//     v2.push_back(56);
//     v2.push_back(11);
//
//     EXPECT_TRUE(sak::is_aligned(&v2[0]));
//
//     v2.push_back(42);
//     v2.push_back(56);
//     v2.push_back(11);
//
//     EXPECT_TRUE(sak::is_aligned(&v2[0]));
//
// }
//
// TEST(TestAlignedAllocator, vector_resize)
// {
//     typedef std::vector<uint8_t, sak::aligned_allocator<uint8_t> >
//     aligned_vector;
//
//     aligned_vector v;
//
//     v.resize(100);
//
//     EXPECT_EQ(v.size(), 100U);
//     v[10] = 0;
// }
//
//
// TEST(TestAlignedAllocator, vector_zero_size)
// {
//     typedef std::vector<uint8_t, sak::aligned_allocator<uint8_t> >
//     aligned_vector;
//
//     aligned_vector v(0);
//     EXPECT_EQ(v.size(), 0U);
// }
<commit_msg>Re-enable test_aligned_allocator.cpp<commit_after>// Copyright (c) 2012, Steinwurf ApS
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Steinwurf ApS nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL Steinwurf ApS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <gtest/gtest.h>
#include <sak/aligned_allocator.hpp>
#include <sak/is_aligned.hpp>

TEST(TestAlignedAllocator, construct)
{
    sak::aligned_allocator<uint8_t> alloc;
    EXPECT_EQ(alloc.alignment(), sak::platform::simd_align);
}

TEST(TestAlignedAllocator, vector)
{
    typedef std::vector<uint32_t, sak::aligned_allocator<uint32_t> >
    aligned_vector;

    aligned_vector v;

    v.push_back(42);
    v.push_back(56);
    v.push_back(11);

    EXPECT_TRUE(sak::is_aligned(&v[0]));

    v.push_back(42);
    v.push_back(56);
    v.push_back(11);

    EXPECT_TRUE(sak::is_aligned(&v[0]));

    v.push_back(42);
    v.push_back(56);
    v.push_back(11);

    EXPECT_TRUE(sak::is_aligned(&v[0]));

    aligned_vector v2 = v;

    EXPECT_TRUE(sak::is_aligned(&v2[0]));

    v2.push_back(42);
    v2.push_back(56);
    v2.push_back(11);

    EXPECT_TRUE(sak::is_aligned(&v2[0]));

    v2.push_back(42);
    v2.push_back(56);
    v2.push_back(11);

    EXPECT_TRUE(sak::is_aligned(&v2[0]));
}

TEST(TestAlignedAllocator, vector_resize)
{
    typedef std::vector<uint8_t, sak::aligned_allocator<uint8_t> >
    aligned_vector;

    aligned_vector v;

    v.resize(100);

    EXPECT_EQ(v.size(), 100U);
    v[10] = 0;
}

TEST(TestAlignedAllocator, vector_zero_size)
{
    typedef std::vector<uint8_t, sak::aligned_allocator<uint8_t> >
    aligned_vector;

    aligned_vector v(0);
    EXPECT_EQ(v.size(), 0U);
}
<|endoftext|>


<commit_before>#include "mod_plate_utils.h"
#include <vw/Plate/Index.h>

#include <httpd.h>
#include <http_protocol.h>
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <vector>
#include <map>

using std::string;

namespace vw {
namespace platefile {

string url_unescape(const string& str) {
  // This is sort of ugly... make sure shared_ptr deletes with free
  boost::shared_ptr<char> bytes(::strdup(str.c_str()), free);
  int ret = ap_unescape_url(bytes.get());
  if (ret != OK)
    vw_throw(BadRequest() << "Invalid query string");

  string unquoted(bytes.get());
  boost::replace_all(unquoted, "+", " ");

  return unquoted;
}

string url_escape(const string& str, apr_pool_t *pool) {
  // this char* will be freed by apache (allocated on request pool), so don't
  // try to free it here.
  char *uri_s = ap_escape_uri(pool, str.c_str());
  return std::string(uri_s);
}

QueryMap::QueryMap(const char *query, apr_pool_t *pool) : m_pool(pool) {
  if (!query || strlen(query) > MAX_QUERY_LENGTH)
    return;

  std::vector<string> items;
  boost::split(items, query, boost::is_any_of(";&"));

  size_t found = 0;
  BOOST_FOREACH(const string& item, items) {
    if (item.empty())
      continue;
    if (found++ >= MAX_KEYS)
      break;
    size_t eq = item.find('=', 1);
    if (eq == string::npos) {
      m_map[url_unescape(item)] = "";
      continue;
    }
    m_map[url_unescape(item.substr(0, eq))] = url_unescape(item.substr(eq+1));
  }
}

string QueryMap::serialize(const std::string& prefix, const std::string& sep) const {
  if (m_map.empty())
    return std::string();

  std::vector<std::string> vals;
  vals.reserve(m_map.size());

  BOOST_FOREACH(const map_t::value_type& p, m_map)
    vals.push_back(url_escape(p.first, m_pool) + "=" + url_escape(p.second, m_pool));

  return prefix + boost::join(vals, sep);
}

string safe_string_convert(const char* in) {
  static const size_t MAX_STRING_LENGTH = 255;

  // string blows up if it's handed null, and could allocate a lot of
  // memory if you let it.
  if (!in || strlen(in) > MAX_STRING_LENGTH)
    return string();
  return string(in);
}

std::streamsize apache_output::write(const char* s, std::streamsize n) {
  return ap_rwrite(s, n, r);
}

WTMLImageSet::WTMLImageSet(
    const string& host,
    const string& data_prefix,
    const string& /*static_prefix*/,
    const string dem_id,
    boost::shared_ptr<const Index> index,
    const string& description)
{
  const IndexHeader& hdr = index->index_header();

  (*this)["Generic"]            = "False";
  (*this)["DataSetType"]        = "Planet";
  (*this)["BandPass"]           = "Visible";
  (*this)["BaseTileLevel"]      = "0";
  (*this)["BaseDegreesPerTile"] = "360";
  (*this)["BottomsUp"]          = "False";
  (*this)["Projection"]         = "Toast";
  (*this)["QuadTreeMap"]        = "0123";
  (*this)["CenterX"]            = "0";
  (*this)["CenterY"]            = "0";
  (*this)["OffsetX"]            = "0";
  (*this)["OffsetY"]            = "0";
  (*this)["Rotation"]           = "0";
  (*this)["Sparse"]             = "True";
  (*this)["ElevationModel"]     = "True";
  (*this)["MeanRadius"]         = "3396000";
  (*this)["StockSet"]           = "False";

  (*this)["Name"]         = description;
  (*this)["FileType"]     = string(".") + hdr.tile_filetype();

  // This is the max index, not the number of levels.
  (*this)["TileLevels"]   = boost::lexical_cast<string>(index->num_levels()-1);

  string data_url = host + data_prefix + vw::stringify(hdr.platefile_id());

  (*this)["Url"]          = data_url + "/{1}/{2}/{3}." + hdr.tile_filetype();
  (*this)["ThumbnailUrl"] = data_url + "/0/0/0."       + hdr.tile_filetype();
  // XXX: This is wrong for non-mars!
  //(*this)["DemUrl"]       = host + static_prefix + "megt128/{0}/{1}/{2}";

  (*this)["DemUrl"]       = host + data_prefix + dem_id + "/{0}/{1}/{2}.toast_dem_v1";

  child_keys.insert("ThumbnailUrl");
  child_keys.insert("Credits");
}

const string& mapget(const std::map<string,string>& map, const std::string& key) {
  std::map<string,string>::const_iterator i = map.find(key);
  if (i == map.end())
    vw::vw_throw(vw::LogicErr() << "WTMLImageSet set up incorrectly");
  return i->second;
}

void WTMLImageSet::serializeToOstream(std::ostream& o) const {
  o << "<ImageSet";
  for (map_t::const_iterator i = this->begin(), end = this->end(); i != end; ++i) {
    if (child_keys.count(i->first) == 0)
      o << " " << i->first << "='" << i->second << "'";
  }
  o << ">" << std::endl;

  BOOST_FOREACH( const string& key, child_keys ) {
    o << "\t<" << key << "><![CDATA[" << mapget(*this, key) << "]]></" << key << ">" << std::endl;
  }
  o << "</ImageSet>" << std::endl;
}

ApacheRequest::ApacheRequest(request_rec* r)
  : r(r), url(safe_string_convert(r->path_info)), args(QueryMap(r->args, r->pool)) {

  // WWT will append &new to dem urls... even when there's no ?.
  if (url.size() > 4 && url.compare(url.size()-4,4,"&new") == 0)
    url.erase(url.size()-4);
}

bool ApacheRequest::header_only() const {
  return r->header_only;
}

request_rec* ApacheRequest::writer() const {
  return r;
}

}} // namespace vw::platefile
<commit_msg>fix mod_plate wtml generation<commit_after>#include "mod_plate_utils.h"
#include <vw/Plate/Index.h>

#include <httpd.h>
#include <http_protocol.h>
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <vector>
#include <map>

using std::string;

namespace vw {
namespace platefile {

string url_unescape(const string& str) {
  // This is sort of ugly... make sure shared_ptr deletes with free
  boost::shared_ptr<char> bytes(::strdup(str.c_str()), free);
  int ret = ap_unescape_url(bytes.get());
  if (ret != OK)
    vw_throw(BadRequest() << "Invalid query string");

  string unquoted(bytes.get());
  boost::replace_all(unquoted, "+", " ");

  return unquoted;
}

string url_escape(const string& str, apr_pool_t *pool) {
  // this char* will be freed by apache (allocated on request pool), so don't
  // try to free it here.
  char *uri_s = ap_escape_uri(pool, str.c_str());
  return std::string(uri_s);
}

QueryMap::QueryMap(const char *query, apr_pool_t *pool) : m_pool(pool) {
  if (!query || strlen(query) > MAX_QUERY_LENGTH)
    return;

  std::vector<string> items;
  boost::split(items, query, boost::is_any_of(";&"));

  size_t found = 0;
  BOOST_FOREACH(const string& item, items) {
    if (item.empty())
      continue;
    if (found++ >= MAX_KEYS)
      break;
    size_t eq = item.find('=', 1);
    if (eq == string::npos) {
      m_map[url_unescape(item)] = "";
      continue;
    }
    m_map[url_unescape(item.substr(0, eq))] = url_unescape(item.substr(eq+1));
  }
}

string QueryMap::serialize(const std::string& prefix, const std::string& sep) const {
  if (m_map.empty())
    return std::string();

  std::vector<std::string> vals;
  vals.reserve(m_map.size());

  BOOST_FOREACH(const map_t::value_type& p, m_map)
    vals.push_back(url_escape(p.first, m_pool) + "=" + url_escape(p.second, m_pool));

  return prefix + boost::join(vals, sep);
}

string safe_string_convert(const char* in) {
  static const size_t MAX_STRING_LENGTH = 255;

  // string blows up if it's handed null, and could allocate a lot of
  // memory if you let it.
  if (!in || strlen(in) > MAX_STRING_LENGTH)
    return string();
  return string(in);
}

std::streamsize apache_output::write(const char* s, std::streamsize n) {
  return ap_rwrite(s, n, r);
}

WTMLImageSet::WTMLImageSet(
    const string& host,
    const string& data_prefix,
    const string& /*static_prefix*/,
    const string dem_id,
    boost::shared_ptr<const Index> index,
    const string& description)
{
  const IndexHeader& hdr = index->index_header();

  (*this)["Generic"]            = "False";
  (*this)["DataSetType"]        = "Planet";
  (*this)["BandPass"]           = "Visible";
  (*this)["BaseTileLevel"]      = "0";
  (*this)["BaseDegreesPerTile"] = "360";
  (*this)["BottomsUp"]          = "False";
  (*this)["Projection"]         = "Toast";
  (*this)["QuadTreeMap"]        = "0123";
  (*this)["CenterX"]            = "0";
  (*this)["CenterY"]            = "0";
  (*this)["OffsetX"]            = "0";
  (*this)["OffsetY"]            = "0";
  (*this)["Rotation"]           = "0";
  (*this)["Sparse"]             = "True";
  (*this)["ElevationModel"]     = "True";
  (*this)["MeanRadius"]         = "3396000";
  (*this)["StockSet"]           = "False";

  (*this)["Name"]         = description;
  (*this)["FileType"]     = string(".") + hdr.tile_filetype();

  // This is the max index, not the number of levels.
  (*this)["TileLevels"]   = boost::lexical_cast<string>(index->num_levels()-1);

  string data_url = host + data_prefix + vw::stringify(hdr.platefile_id());

  (*this)["Url"]          = data_url + "/{1}/{2}/{3}." + hdr.tile_filetype();
  (*this)["ThumbnailUrl"] = data_url + "/0/0/0."       + hdr.tile_filetype();

  // XXX: This is wrong for non-mars!
  (*this)["DemUrl"]       = host + data_prefix + dem_id + "/{0}/{1}/{2}.toast_dem_v1";

  // This probably needs to be in the plate somewhere...
  (*this)["Credits"]      = "";

  child_keys.insert("ThumbnailUrl");
  child_keys.insert("Credits");
}

const string& mapget(const std::map<string,string>& map, const std::string& key) {
  std::map<string,string>::const_iterator i = map.find(key);
  if (i == map.end())
    vw::vw_throw(vw::LogicErr() << "WTMLImageSet set up incorrectly (could not find required key " << key << ")");
  return i->second;
}

void WTMLImageSet::serializeToOstream(std::ostream& o) const {
  o << "<ImageSet";
  for (map_t::const_iterator i = this->begin(), end = this->end(); i != end; ++i) {
    if (child_keys.count(i->first) == 0)
      o << " " << i->first << "='" << i->second << "'";
  }
  o << ">" << std::endl;

  BOOST_FOREACH( const string& key, child_keys ) {
    o << "\t<" << key << "><![CDATA[" << mapget(*this, key) << "]]></" << key << ">" << std::endl;
  }
  o << "</ImageSet>" << std::endl;
}

ApacheRequest::ApacheRequest(request_rec* r)
  : r(r), url(safe_string_convert(r->path_info)), args(QueryMap(r->args, r->pool)) {

  // WWT will append &new to dem urls... even when there's no ?.
  if (url.size() > 4 && url.compare(url.size()-4,4,"&new") == 0)
    url.erase(url.size()-4);
}

bool ApacheRequest::header_only() const {
  return r->header_only;
}

request_rec* ApacheRequest::writer() const {
  return r;
}

}} // namespace vw::platefile
<|endoftext|>


<commit_before>#include "messageFactory.h"

#include "libwatcher/message.h"
#include "libwatcher/labelMessage.h"
#include "libwatcher/edgeMessage.h"
#include "libwatcher/colorMessage.h"
#include "libwatcher/gpsMessage.h"
#include "libwatcher/messageStatus.h"
#include "libwatcher/dataRequestMessage.h"
#include "libwatcher/testMessage.h"
#include "libwatcher/seekWatcherMessage.h"
#include "libwatcher/startWatcherMessage.h"
#include "libwatcher/stopWatcherMessage.h"
#include "libwatcher/speedWatcherMessage.h"

using namespace watcher;
using namespace watcher::event;

INIT_LOGGER(MessageFactory, "MessageFactory");

// static
boost::shared_ptr<Message> MessageFactory::makeMessage(const MessageType &type)
{
    switch(type)
    {
        case MESSAGE_STATUS_TYPE:
            return MessageStatusPtr(new MessageStatus);
            break;
        case TEST_MESSAGE_TYPE:
            return TestMessagePtr(new TestMessage);
            break;
        case GPS_MESSAGE_TYPE:
            return GPSMessagePtr(new GPSMessage);
            break;
        case LABEL_MESSAGE_TYPE:
            return LabelMessagePtr(new LabelMessage);
            break;
        case EDGE_MESSAGE_TYPE:
            return EdgeMessagePtr(new EdgeMessage);
            break;
        case COLOR_MESSAGE_TYPE:
            return ColorMessagePtr(new ColorMessage);
            break;
        case DATA_REQUEST_MESSAGE_TYPE:
            return DataRequestMessagePtr(new DataRequestMessage);
            break;
        case SEEK_MESSAGE_TYPE:
            return SeekMessagePtr(new SeekMessage);
            break;
        case START_MESSAGE_TYPE:
            return StartMessagePtr(new StartMessage);
            break;
        case STOP_MESSAGE_TYPE:
            return StopMessagePtr(new StopMessage);
            break;
        case SPEED_MESSAGE_TYPE:
            return SpeedMessagePtr(new SpeedMessage);
            break;

            // let used defined and unknown fall through - a NULL will be returned.
        case UNKNOWN_MESSAGE_TYPE:
        case USER_DEFINED_MESSAGE_TYPE:
            break;

            // GTL - do not put a default or the compiler
            // won't tell us when we've missed a case.
    }
    return MessagePtr(); // == NULL
}

<commit_msg>messageFactory: handle NODE_STATUS_MESSAGE_TYPE type.<commit_after>#include "messageFactory.h"

#include "libwatcher/message.h"
#include "libwatcher/labelMessage.h"
#include "libwatcher/edgeMessage.h"
#include "libwatcher/colorMessage.h"
#include "libwatcher/gpsMessage.h"
#include "libwatcher/messageStatus.h"
#include "libwatcher/dataRequestMessage.h"
#include "libwatcher/testMessage.h"
#include "libwatcher/seekWatcherMessage.h"
#include "libwatcher/startWatcherMessage.h"
#include "libwatcher/stopWatcherMessage.h"
#include "libwatcher/speedWatcherMessage.h"
#include "libwatcher/nodeStatusMessage.h"

using namespace watcher;
using namespace watcher::event;

INIT_LOGGER(MessageFactory, "MessageFactory");

// static
boost::shared_ptr<Message> MessageFactory::makeMessage(const MessageType &type)
{
    switch(type)
    {
        case MESSAGE_STATUS_TYPE:
            return MessageStatusPtr(new MessageStatus);
            break;
        case TEST_MESSAGE_TYPE:
            return TestMessagePtr(new TestMessage);
            break;
        case GPS_MESSAGE_TYPE:
            return GPSMessagePtr(new GPSMessage);
            break;
        case LABEL_MESSAGE_TYPE:
            return LabelMessagePtr(new LabelMessage);
            break;
        case EDGE_MESSAGE_TYPE:
            return EdgeMessagePtr(new EdgeMessage);
            break;
        case COLOR_MESSAGE_TYPE:
            return ColorMessagePtr(new ColorMessage);
            break;
        case DATA_REQUEST_MESSAGE_TYPE:
            return DataRequestMessagePtr(new DataRequestMessage);
            break;
        case SEEK_MESSAGE_TYPE:
            return SeekMessagePtr(new SeekMessage);
            break;
        case START_MESSAGE_TYPE:
            return StartMessagePtr(new StartMessage);
            break;
        case STOP_MESSAGE_TYPE:
            return StopMessagePtr(new StopMessage);
            break;
        case SPEED_MESSAGE_TYPE:
            return SpeedMessagePtr(new SpeedMessage);
            break;
        case NODE_STATUS_MESSAGE_TYPE:
            return NodeStatusMessagePtr(new NodeStatusMessage);
            break;

            // let used defined and unknown fall through - a NULL will be returned.
        case UNKNOWN_MESSAGE_TYPE:
        case USER_DEFINED_MESSAGE_TYPE:
            break;

            // GTL - do not put a default or the compiler
            // won't tell us when we've missed a case.
    }
    return MessagePtr(); // == NULL
}

<|endoftext|>