<commit_before>/*****************************************************************************
 * Project: BaBar detector at the SLAC PEP-II B-factory
 * Package: RooFitCore
 *    File: $Id: RooStreamParser.cc,v 1.6 2001/07/31 05:54:22 verkerke Exp $
 * Authors:
 *   DK, David Kirkby, Stanford University, kirkby@hep.stanford.edu
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu
 * History:
 *   07-Mar-2001 WV Created initial version
 *
 * Copyright (C) 2001 University of California
 *****************************************************************************/

// -- CLASS DESCRIPTION --
// RooStreamParser is a utility class to parse istreams into tokens and optionally
// convert them into basic types (double,int,string)
//
// The general tokenizing philosophy is that there are two kinds of tokens: value
// and punctuation. The former are variable length, the latter always
// one character. A token is terminated if one of the following conditions
// occur
//         - space character found (' ',tab,newline)
//         - change of token type (value -> punctuation or vv)
//         - end of fixed-length token (punctuation only)
//         - start or end of quoted string
//
// The parser is aware of floating point notation and will assign leading
// minus signs, decimal points etc to a value token when this is obvious
// from the context. The definition of what is punctuation can be redefined.

#include <iostream.h>
#include <stdlib.h>
#include <ctype.h>
#include "RooFitCore/RooStreamParser.hh"

ClassImp(RooStreamParser)

RooStreamParser::RooStreamParser(istream& is) :
  _is(is), _prefix(""), _punct("()[]<>|/\\:?.,=+-&^%$#@!`~")
{
  // Constructor
}

RooStreamParser::RooStreamParser(istream& is, const TString& errorPrefix) :
  _is(is), _prefix(errorPrefix), _punct("()[]<>|/\\:?.,=+-&^%$#@!`~")
{
  // Constructor with error message prefix
}

RooStreamParser::~RooStreamParser()
{
  // Destructor
}

void RooStreamParser::setPunctuation(const TString& punct)
{
  // Change list of punctuation characters
  _punct = punct ;
}

Bool_t RooStreamParser::isPunctChar(char c) const
{
  // Check if given char is considered punctuation
  const char* punct = _punct.Data() ;
  for (int i=0 ; i<_punct.Length() ; i++)
    if (punct[i] == c) {
      return kTRUE ;
    }
  return kFALSE ;
}

TString RooStreamParser::readToken()
{
  // Read one token

  // Smart tokenizer. Absorb white space and token must be either punctuation or alphanum
  Bool_t first(kTRUE), quotedString(kFALSE) ;
  char buffer[1024], c, cnext, cprev=' ' ;
  Int_t bufptr(0) ;

  //Ignore leading newline
  if (_is.peek()=='\n') _is.get(c) ;

  while(1) {
    // Buffer overflow protection
    if (bufptr>=1020) {
      cout << "RooStreamParser::readToken: token length exceeds buffer capacity, terminating token early" << endl ;
      break ;
    }

    // Read next char
    _is.get(c) ;

    // Terminate at EOF, EOL or trouble
    if (!_is.good() || c=='\n') break ;

    // Terminate as SPACE, unless we haven't seen any non-SPACE yet
    if (isspace(c)) {
      if (first)
	continue ;
      else
	if (!quotedString) {
	  break ;
	}
    }

    // If '-' or '/' see what the next character is
    if (c == '.' || c=='-' || c=='/') {
      _is.get(cnext) ;
      _is.putback(cnext) ;
    }

    // Stop if begin of comments is encountered
    if (c=='/' && cnext=='/') {
      zapToEnd() ;
      break ;
    }

    // Special handling of quoted strings
    if (c=='"') {
      if (first) {
	quotedString=kTRUE ;
      } else if (!quotedString) {
	// Terminate current token. Next token will be quoted string
	_is.putback('"') ;
	break ;
      }
    }

    if (!quotedString) {
      // Decide if next char is punctuation (exempt - and . that are part of floating point numbers)
      if (isPunctChar(c) && !(c=='.' && (isdigit(cnext)||isdigit(cprev)))
	  && !(c=='-' && (isdigit(cnext)||cnext=='.'))) {
	if (first) {
	  // Make this a one-char punctuation token
	  buffer[bufptr++]=c ;
	  break ;
	} else {
	  // Put back punct. char and terminate current alphanum token
	  _is.putback(c) ;
	  break ;
	}
      }
    } else {
      // Inside quoted string conventional tokenizing rules do not apply

      // Terminate token on closing quote
      if (c=='"' && !first) {
	buffer[bufptr++]=c ;
	quotedString=kFALSE ;
	break ;
      }
    }

    // Store in buffer
    buffer[bufptr++]=c ;
    first=kFALSE ;
    cprev=c ;
  }

  // Check if closing quote was encountered
  if (quotedString) {
    cout << "RooStreamParser::readToken: closing quote (\") missing" << endl ;
  }

  // Absorb trailing white space or absorb rest of line if // is encountered
  if (c=='\n') {
    _is.putback(c) ;
  } else {
    c = _is.peek() ;

    while ((isspace(c) || c=='/') && c != '\n') {
      if (c=='/') {
	_is.get(c) ;
	if (_is.peek()=='/') {
	  zapToEnd() ;
	} else {
	  _is.putback('/') ;
	}
	break ;
      } else {
	_is.get(c) ;
	c = _is.peek() ;
      }
    }
  }

  // Zero terminate buffer and convert to TString
  buffer[bufptr]=0 ;
  return TString(buffer) ;
}

TString RooStreamParser::readLine()
{
  // Read an entire line

  char c,buffer[1024] ;

  if (_is.peek()=='\n') _is.get(c) ;

  // Read till end of line
  _is.getline(buffer,1023,'\n') ;

  // Chop eventual comments
  char *pcomment = strstr(buffer,"//") ;
  if (pcomment) *pcomment=0 ;

  // Chop leading and trailing space
  char *pstart=buffer ;
  while (isspace(*pstart)) {
    pstart++ ;
  }
  char *pend=buffer+strlen(buffer)-1 ;
  if (pend>pstart)
    while (isspace(*pend)) { *pend--=0 ; }

  // Convert to TString
  return TString(pstart) ;
}

void RooStreamParser::zapToEnd()
{
  // Skip over everything until the end of the current line
  if (!_is.peek()!='\n') {
    _is.ignore(1000,'\n') ;
    _is.putback('\n') ;
  }
}

void RooStreamParser::putBackToken(const TString& token)
{
  // Put back given token in stream buffer

  const char* buf=token.Data() ;
  int len=token.Length() ;
  for (int i=len-1 ; i>=0 ; i--)
    _is.putback(buf[i]) ;

  // Add a space to keep the token separate
  if (buf[0]=='\n') {
  } else {
  _is.putback(' ') ;
  }
}

Bool_t RooStreamParser::expectToken(const TString& expected, Bool_t zapOnError)
{
  // Read a token and check if it matches the given expected value
  TString token(readToken()) ;

  Bool_t error=token.CompareTo(expected) ;
  if (error && !_prefix.IsNull()) {
    cout << _prefix << ": parse error, expected '"
	 << expected << "'" << ", got '" << token << "'" << endl ;
    if (zapOnError) zapToEnd() ;
  }
  return error ;
}

Bool_t RooStreamParser::readDouble(Double_t& value, Bool_t zapOnError)
{
  // Read a token and convert it to a Double_t
  TString token(readToken()) ;
  if (token.IsNull()) return kTRUE ;
  return convertToDouble(token,value) ;

}

Bool_t RooStreamParser::convertToDouble(const TString& token, Double_t& value)
{
  // Convert given string to a double
  char* endptr(0) ;
  const char* data=token.Data() ;
  value = strtod(data,&endptr) ;
  Bool_t error = (endptr-data!=token.Length()) ;

  if (error && !_prefix.IsNull()) {
    cout << _prefix << ": parse error, cannot convert '"
	 << token << "'" << " to double precision" <<  endl ;
  }
  return error ;
}

Bool_t RooStreamParser::readInteger(Int_t value, Bool_t zapOnError)
{
  // Read a token and convert it to an Int_t
  TString token(readToken()) ;
  if (token.IsNull()) return kTRUE ;
  return convertToInteger(token,value) ;
}

Bool_t RooStreamParser::convertToInteger(const TString& token, Int_t& value)
{
  // Convert given string to an Int_t
  char* endptr(0) ;
  const char* data=token.Data() ;
  value = strtol(data,&endptr,10) ;
  Bool_t error = (endptr-data!=token.Length()) ;

  if (error && !_prefix.IsNull()) {
    cout << _prefix << ": parse error, cannot convert '"
	 << token << "'" << " to integer" <<  endl ;
  }
  return error ;
}

Bool_t RooStreamParser::readString(TString& value, Bool_t zapOnError)
{
  // Read a string token
  TString token(readToken()) ;
  if (token.IsNull()) return kTRUE ;
  return convertToString(token,value) ;
}

Bool_t RooStreamParser::convertToString(const TString& token, TString& string)
{
  // Convert given token to a string (i.e. remove eventual quotation marks)

  // Transport to buffer
  char buffer[1024],*ptr ;
  strncpy(buffer,token.Data(),1023) ;
  if (token.Length()>=1023) {
    cout << "RooStreamParser::convertToString: token length exceeds 1023, truncated" << endl ;
    buffer[1023]=0 ;
  }
  int len = strlen(buffer) ;

  // Remove trailing quote if any
  if ((len) && (buffer[len-1]=='"'))
    buffer[len-1]=0 ;

  // Skip leading quote, if present
  ptr=(buffer[0]=='"') ? buffer+1 : buffer ;

  string = ptr ;
  return kFALSE ;
}

<commit_msg><commit_after>/*****************************************************************************
 * Project: BaBar detector at the SLAC PEP-II B-factory
 * Package: RooFitCore
 *    File: $Id: RooStreamParser.cc,v 1.7 2001/08/15 23:38:44 verkerke Exp $
 * Authors:
 *   DK, David Kirkby, Stanford University, kirkby@hep.stanford.edu
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu
 * History:
 *   07-Mar-2001 WV Created initial version
 *
 * Copyright (C) 2001 University of California
 *****************************************************************************/

// -- CLASS DESCRIPTION --
// RooStreamParser is a utility class to parse istreams into tokens and optionally
// convert them into basic types (double,int,string)
//
// The general tokenizing philosophy is that there are two kinds of tokens: value
// and punctuation. The former are variable length, the latter always
// one character. A token is terminated if one of the following conditions
// occur
//         - space character found (' ',tab,newline)
//         - change of token type (value -> punctuation or vv)
//         - end of fixed-length token (punctuation only)
//         - start or end of quoted string
//
// The parser is aware of floating point notation and will assign leading
// minus signs, decimal points etc to a value token when this is obvious
// from the context. The definition of what is punctuation can be redefined.

#include <iostream.h>
#include <stdlib.h>
#include <ctype.h>
#include "RooFitCore/RooStreamParser.hh"

ClassImp(RooStreamParser)

RooStreamParser::RooStreamParser(istream& is) :
  _is(is), _prefix(""), _punct("()[]<>|/\\:?.,=+-&^%$#@!`~")
{
  // Constructor
}

RooStreamParser::RooStreamParser(istream& is, const TString& errorPrefix) :
  _is(is), _prefix(errorPrefix), _punct("()[]<>|/\\:?.,=+-&^%$#@!`~")
{
  // Constructor with error message prefix
}

RooStreamParser::~RooStreamParser()
{
  // Destructor
}

void RooStreamParser::setPunctuation(const TString& punct)
{
  // Change list of punctuation characters
  _punct = punct ;
}

Bool_t RooStreamParser::isPunctChar(char c) const
{
  // Check if given char is considered punctuation
  const char* punct = _punct.Data() ;
  for (int i=0 ; i<_punct.Length() ; i++)
    if (punct[i] == c) {
      return kTRUE ;
    }
  return kFALSE ;
}

TString RooStreamParser::readToken()
{
  // Read one token

  // Smart tokenizer. Absorb white space and token must be either punctuation or alphanum
  Bool_t first(kTRUE), quotedString(kFALSE) ;
  char buffer[1024], c, cnext, cprev=' ' ;
  Int_t bufptr(0) ;

  //Ignore leading newline
  if (_is.peek()=='\n') {
    _is.get(c) ;

    // If new line starts with #, zap it
    while (_is.peek()=='#') {
      zapToEnd() ;
      _is.get(c) ; // absorb newline
    }
  }

  while(1) {
    // Buffer overflow protection
    if (bufptr>=1020) {
      cout << "RooStreamParser::readToken: token length exceeds buffer capacity, terminating token early" << endl ;
      break ;
    }

    // Read next char
    _is.get(c) ;

    // Terminate at EOF, EOL or trouble
    if (!_is.good() || c=='\n') break ;

    // Terminate as SPACE, unless we haven't seen any non-SPACE yet
    if (isspace(c)) {
      if (first)
	continue ;
      else
	if (!quotedString) {
	  break ;
	}
    }

    // If '-' or '/' see what the next character is
    if (c == '.' || c=='-' || c=='/') {
      _is.get(cnext) ;
      _is.putback(cnext) ;
    }

    // Stop if begin of comments is encountered
    if (c=='/' && cnext=='/') {
      zapToEnd() ;
      break ;
    }

    // Special handling of quoted strings
    if (c=='"') {
      if (first) {
	quotedString=kTRUE ;
      } else if (!quotedString) {
	// Terminate current token. Next token will be quoted string
	_is.putback('"') ;
	break ;
      }
    }

    if (!quotedString) {
      // Decide if next char is punctuation (exempt - and . that are part of floating point numbers)
      if (isPunctChar(c) && !(c=='.' && (isdigit(cnext)||isdigit(cprev)))
	  && !(c=='-' && (isdigit(cnext)||cnext=='.'))) {
	if (first) {
	  // Make this a one-char punctuation token
	  buffer[bufptr++]=c ;
	  break ;
	} else {
	  // Put back punct. char and terminate current alphanum token
	  _is.putback(c) ;
	  break ;
	}
      }
    } else {
      // Inside quoted string conventional tokenizing rules do not apply

      // Terminate token on closing quote
      if (c=='"' && !first) {
	buffer[bufptr++]=c ;
	quotedString=kFALSE ;
	break ;
      }
    }

    // Store in buffer
    buffer[bufptr++]=c ;
    first=kFALSE ;
    cprev=c ;
  }

  // Check if closing quote was encountered
  if (quotedString) {
    cout << "RooStreamParser::readToken: closing quote (\") missing" << endl ;
  }

  // Absorb trailing white space or absorb rest of line if // is encountered
  if (c=='\n') {
    _is.putback(c) ;
  } else {
    c = _is.peek() ;

    while ((isspace(c) || c=='/') && c != '\n') {
      if (c=='/') {
	_is.get(c) ;
	if (_is.peek()=='/') {
	  zapToEnd() ;
	} else {
	  _is.putback('/') ;
	}
	break ;
      } else {
	_is.get(c) ;
	c = _is.peek() ;
      }
    }
  }

  // Zero terminate buffer and convert to TString
  buffer[bufptr]=0 ;
  return TString(buffer) ;
}

TString RooStreamParser::readLine()
{
  // Read an entire line

  char c,buffer[1024] ;

  if (_is.peek()=='\n') _is.get(c) ;

  // Read till end of line
  _is.getline(buffer,1023,'\n') ;

  // Chop eventual comments
  char *pcomment = strstr(buffer,"//") ;
  if (pcomment) *pcomment=0 ;

  // Chop leading and trailing space
  char *pstart=buffer ;
  while (isspace(*pstart)) {
    pstart++ ;
  }
  char *pend=buffer+strlen(buffer)-1 ;
  if (pend>pstart)
    while (isspace(*pend)) { *pend--=0 ; }

  // Convert to TString
  return TString(pstart) ;
}

void RooStreamParser::zapToEnd()
{
  // Skip over everything until the end of the current line
  if (!_is.peek()!='\n') {
    _is.ignore(1000,'\n') ;
    _is.putback('\n') ;
  }
}

void RooStreamParser::putBackToken(const TString& token)
{
  // Put back given token in stream buffer

  const char* buf=token.Data() ;
  int len=token.Length() ;
  for (int i=len-1 ; i>=0 ; i--)
    _is.putback(buf[i]) ;

  // Add a space to keep the token separate
  if (buf[0]=='\n') {
  } else {
  _is.putback(' ') ;
  }
}

Bool_t RooStreamParser::expectToken(const TString& expected, Bool_t zapOnError)
{
  // Read a token and check if it matches the given expected value
  TString token(readToken()) ;

  Bool_t error=token.CompareTo(expected) ;
  if (error && !_prefix.IsNull()) {
    cout << _prefix << ": parse error, expected '"
	 << expected << "'" << ", got '" << token << "'" << endl ;
    if (zapOnError) zapToEnd() ;
  }
  return error ;
}

Bool_t RooStreamParser::readDouble(Double_t& value, Bool_t zapOnError)
{
  // Read a token and convert it to a Double_t
  TString token(readToken()) ;
  if (token.IsNull()) return kTRUE ;
  return convertToDouble(token,value) ;

}

Bool_t RooStreamParser::convertToDouble(const TString& token, Double_t& value)
{
  // Convert given string to a double
  char* endptr(0) ;
  const char* data=token.Data() ;
  value = strtod(data,&endptr) ;
  Bool_t error = (endptr-data!=token.Length()) ;

  if (error && !_prefix.IsNull()) {
    cout << _prefix << ": parse error, cannot convert '"
	 << token << "'" << " to double precision" <<  endl ;
  }
  return error ;
}

Bool_t RooStreamParser::readInteger(Int_t value, Bool_t zapOnError)
{
  // Read a token and convert it to an Int_t
  TString token(readToken()) ;
  if (token.IsNull()) return kTRUE ;
  return convertToInteger(token,value) ;
}

Bool_t RooStreamParser::convertToInteger(const TString& token, Int_t& value)
{
  // Convert given string to an Int_t
  char* endptr(0) ;
  const char* data=token.Data() ;
  value = strtol(data,&endptr,10) ;
  Bool_t error = (endptr-data!=token.Length()) ;

  if (error && !_prefix.IsNull()) {
    cout << _prefix << ": parse error, cannot convert '"
	 << token << "'" << " to integer" <<  endl ;
  }
  return error ;
}

Bool_t RooStreamParser::readString(TString& value, Bool_t zapOnError)
{
  // Read a string token
  TString token(readToken()) ;
  if (token.IsNull()) return kTRUE ;
  return convertToString(token,value) ;
}

Bool_t RooStreamParser::convertToString(const TString& token, TString& string)
{
  // Convert given token to a string (i.e. remove eventual quotation marks)

  // Transport to buffer
  char buffer[1024],*ptr ;
  strncpy(buffer,token.Data(),1023) ;
  if (token.Length()>=1023) {
    cout << "RooStreamParser::convertToString: token length exceeds 1023, truncated" << endl ;
    buffer[1023]=0 ;
  }
  int len = strlen(buffer) ;

  // Remove trailing quote if any
  if ((len) && (buffer[len-1]=='"'))
    buffer[len-1]=0 ;

  // Skip leading quote, if present
  ptr=(buffer[0]=='"') ? buffer+1 : buffer ;

  string = ptr ;
  return kFALSE ;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: basdoc.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2003-09-19 08:29:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <ide_pch.hxx>

#pragma hdrstop

#define GLOBALOVERFLOW2

#include <sfx2/docfac.hxx>

#ifndef _SV_STATUS_HXX //autogen
#include <vcl/status.hxx>
#endif

#include <basdoc.hxx>
#include <basidesh.hrc>

#define BasicDocShell
#include <basslots.hxx>

#include "basicmod.hxx"
#include "unomodel.hxx"

TYPEINIT1(BasicDocShell, SfxObjectShell);
DBG_NAME(BasicDocShell);

SFX_IMPL_SIMPLE_OBJECTFACTORY( BasicDocShell, SFXOBJECTSHELL_STD_NORMAL, sbasic )
{
    Factory().SetExplorerImageId( IMG_MACROLIB );
    Factory().RegisterHelpFile( String( RTL_CONSTASCII_USTRINGPARAM( "sbasic" ) ) );
    Factory().SetDocumentServiceName( String::CreateFromAscii("com.sun.star.comp.basic.BasidIDE") );
    Factory().RegisterMenuBar( IDEResId(RID_BASICMENU) );
}

SFX_IMPL_INTERFACE( BasicDocShell, SfxObjectShell, IDEResId( 0 ) )
{
    SFX_STATUSBAR_REGISTRATION( SID_BASICIDE_STATUSBAR );
}

BasicDocShell::BasicDocShell( SfxObjectCreateMode eMode ) : SfxObjectShell( eMode )
{
    pPrinter = 0;
    SetPool( &SFX_APP()->GetPool() );
    SetTitle( String( RTL_CONSTASCII_USTRINGPARAM("BASIC") ) );
    SetModel( new SIDEModel(this) );
}

__EXPORT BasicDocShell::~BasicDocShell()
{
    delete pPrinter;
}

void __EXPORT BasicDocShell::Execute( SfxRequest& rReq )
{
}

void __EXPORT BasicDocShell::GetState(SfxItemSet &rSet)
{
}

SfxPrinter* BasicDocShell::GetPrinter( BOOL bCreate )
{
    if ( !pPrinter && bCreate )
        pPrinter = new SfxPrinter( new SfxItemSet( GetPool(), SID_PRINTER_NOTFOUND_WARN , SID_PRINTER_NOTFOUND_WARN ) );

    return pPrinter;
}

void BasicDocShell::SetPrinter( SfxPrinter* pPr )
{
    if ( pPr != pPrinter )
    {
        delete pPrinter;
        pPrinter = pPr;
    }
}

void BasicDocShell::FillStatusBar( StatusBar& rStatusBar )
{
    String aTmp;

    // Titel
    aTmp.Fill( 30, 'X' );
    rStatusBar.InsertItem( SID_BASICIDE_STAT_TITLE,
        rStatusBar.GetTextWidth( aTmp ), SIB_AUTOSIZE | SIB_LEFT);

    // Modify
    rStatusBar.InsertItem( SID_DOC_MODIFIED,
        rStatusBar.GetTextWidth( '*' ) );

    // Position
    aTmp.Erase();
    aTmp.Fill( 15, 'X' );
    rStatusBar.InsertItem( SID_BASICIDE_STAT_POS,
        rStatusBar.GetTextWidth( aTmp ), SIB_LEFT);

    // Insert/Overwrite
    rStatusBar.InsertItem( SID_ATTR_INSERT,
        rStatusBar.GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM( "XXXXX" /* "EINFG" */ ) ) ) );

    // Uhrzeit
    aTmp.Fill( 20, 'X' );
    rStatusBar.InsertItem( SID_ATTR_SIZE,
        rStatusBar.GetTextWidth( aTmp ), SIB_AUTOSIZE | SIB_LEFT | SIB_USERDRAW );

//  return pStatusBar;

}

<commit_msg>INTEGRATION: CWS filtercfg (1.9.8); FILE MERGED 2003/10/30 16:42:53 mba 1.9.8.1: #112834#: typo<commit_after>/*************************************************************************
 *
 *  $RCSfile: basdoc.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: kz $ $Date: 2004-01-28 12:56:30 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <ide_pch.hxx>

#pragma hdrstop

#define GLOBALOVERFLOW2

#include <sfx2/docfac.hxx>

#ifndef _SV_STATUS_HXX //autogen
#include <vcl/status.hxx>
#endif

#include <basdoc.hxx>
#include <basidesh.hrc>

#define BasicDocShell
#include <basslots.hxx>

#include "basicmod.hxx"
#include "unomodel.hxx"

TYPEINIT1(BasicDocShell, SfxObjectShell);
DBG_NAME(BasicDocShell);

SFX_IMPL_SIMPLE_OBJECTFACTORY( BasicDocShell, SFXOBJECTSHELL_STD_NORMAL, sbasic )
{
    Factory().SetExplorerImageId( IMG_MACROLIB );
    Factory().RegisterHelpFile( String( RTL_CONSTASCII_USTRINGPARAM( "sbasic" ) ) );
    Factory().SetDocumentServiceName( String::CreateFromAscii("com.sun.star.comp.basic.BasicIDE") );
    Factory().RegisterMenuBar( IDEResId(RID_BASICMENU) );
}

SFX_IMPL_INTERFACE( BasicDocShell, SfxObjectShell, IDEResId( 0 ) )
{
    SFX_STATUSBAR_REGISTRATION( SID_BASICIDE_STATUSBAR );
}

BasicDocShell::BasicDocShell( SfxObjectCreateMode eMode ) : SfxObjectShell( eMode )
{
    pPrinter = 0;
    SetPool( &SFX_APP()->GetPool() );
    SetTitle( String( RTL_CONSTASCII_USTRINGPARAM("BASIC") ) );
    SetModel( new SIDEModel(this) );
}

__EXPORT BasicDocShell::~BasicDocShell()
{
    delete pPrinter;
}

void __EXPORT BasicDocShell::Execute( SfxRequest& rReq )
{
}

void __EXPORT BasicDocShell::GetState(SfxItemSet &rSet)
{
}

SfxPrinter* BasicDocShell::GetPrinter( BOOL bCreate )
{
    if ( !pPrinter && bCreate )
        pPrinter = new SfxPrinter( new SfxItemSet( GetPool(), SID_PRINTER_NOTFOUND_WARN , SID_PRINTER_NOTFOUND_WARN ) );

    return pPrinter;
}

void BasicDocShell::SetPrinter( SfxPrinter* pPr )
{
    if ( pPr != pPrinter )
    {
        delete pPrinter;
        pPrinter = pPr;
    }
}

void BasicDocShell::FillStatusBar( StatusBar& rStatusBar )
{
    String aTmp;

    // Titel
    aTmp.Fill( 30, 'X' );
    rStatusBar.InsertItem( SID_BASICIDE_STAT_TITLE,
        rStatusBar.GetTextWidth( aTmp ), SIB_AUTOSIZE | SIB_LEFT);

    // Modify
    rStatusBar.InsertItem( SID_DOC_MODIFIED,
        rStatusBar.GetTextWidth( '*' ) );

    // Position
    aTmp.Erase();
    aTmp.Fill( 15, 'X' );
    rStatusBar.InsertItem( SID_BASICIDE_STAT_POS,
        rStatusBar.GetTextWidth( aTmp ), SIB_LEFT);

    // Insert/Overwrite
    rStatusBar.InsertItem( SID_ATTR_INSERT,
        rStatusBar.GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM( "XXXXX" /* "EINFG" */ ) ) ) );

    // Uhrzeit
    aTmp.Fill( 20, 'X' );
    rStatusBar.InsertItem( SID_ATTR_SIZE,
        rStatusBar.GetTextWidth( aTmp ), SIB_AUTOSIZE | SIB_LEFT | SIB_USERDRAW );

//  return pStatusBar;

}

<|endoftext|>


<commit_before>#include <QString>
#include <QStringList>
#include <functional>
#include <future>
#include <memory>
#include "kernel.h"
#include "coverage.h"
#include "columndefinition.h"
#include "table.h"
#include "attributerecord.h"
#include "feature.h"
#include "featurecoverage.h"
#include "symboltable.h"
#include "OperationExpression.h"
#include "operationmetadata.h"
#include "operation.h"
#include "operationhelper.h"
#include "operationhelperfeatures.h"
#include "commandhandler.h"
#include "featureiterator.h"
#include "ifoperation.h"
#include "iffeature.h"

using namespace Ilwis;
using namespace BaseOperations;

REGISTER_OPERATION(IfFeature)

Ilwis::BaseOperations::IfFeature::IfFeature()
{
}

IfFeature::IfFeature(quint64 metaid, const Ilwis::OperationExpression &expr) : IfOperation(metaid, expr)
{
}

bool IfFeature::execute(ExecutionContext *ctx, SymbolTable &symTable)
{
    if (_prepState == sNOTPREPARED)
        if((_prepState = prepare(ctx, symTable)) != sPREPARED)
            return false;

    SubSetAsyncFunc iffunc = [&](const std::vector<quint32>& subset) -> bool {

        FeatureIterator iterOut(_outputFC);
        FeatureIterator iterIn(_inputFC,subset);
        FeatureIterator iterEnd = iterOut.end();
        while(iterIn != iterEnd) {
            _outputFC->newFeatureFrom(*iterIn);

            ++iterOut;
            ++iterIn;
        }
        return true;

    };

    bool resource = OperationHelperFeatures::execute(ctx, iffunc, _inputFC, _outputFC);

    if ( resource && ctx != 0) {
        QVariant value;
        value.setValue<IFeatureCoverage>(_outputFC);
        ctx->setOutput(symTable,value,_outputFC->name(),itFEATURE,_outputFC->source());
    }
    return true;
}

Ilwis::OperationImplementation *IfFeature::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new IfFeature(metaid, expr);
}

Ilwis::OperationImplementation::State IfFeature::prepare(ExecutionContext *ctx, const SymbolTable &)
{
    QString fc = _expression.parm(0).value();

    if (!_inputFC.prepare(fc)) {
        ERROR2(ERR_COULD_NOT_LOAD_2,fc,"");
        return sPREPAREFAILED;
    }

    OperationHelperFeatures helper;
    IIlwisObject obj = helper.initialize(_inputFC.as<IlwisObject>(), itFEATURE, itENVELOPE | itCOORDSYSTEM) ;
    if ( !obj.isValid()) {
        ERROR2(ERR_INVALID_INIT_FOR_2,"FeatureCoverage",fc);
        return sPREPAREFAILED;
    }
    _outputFC = obj.as<FeatureCoverage>();

//    DataDefinition outputDataDef = findOutputDataDef(_expression);
//    _outputFC->datadef() = outputDataDef;

    return sPREPARED;
}

quint64 IfFeature::createMetadata()
{
    QString url = QString("ilwis://operations/iff");
    Resource resource(QUrl(url), itOPERATIONMETADATA);
    resource.addProperty("namespace","ilwis");
    resource.addProperty("longname","iff");
    resource.addProperty("syntax","iffraster(featurecoverage,outputchoicetrue, outputchoicefalse)");
    resource.addProperty("description","constructs a new coverage based on a boolean selection described by the boolean map. The true pixels are taken from the first input map, the false pixels from the second map");
    resource.addProperty("inparameters","3");
    resource.addProperty("pin_1_type", itFEATURE);
    resource.addProperty("pin_1_name", TR("input featurecoverage"));
    resource.addProperty("pin_1_desc",TR("input featurecoverage with boolean domain"));
    resource.addProperty("pin_2_type", itNUMBER | itSTRING | itBOOL | itFEATURE);
    resource.addProperty("pin_2_name", TR("true choice"));
    resource.addProperty("pin_2_desc",TR("value returned when the boolean input feature is true"));
    resource.addProperty("pin_3_type", itNUMBER | itSTRING | itBOOL | itFEATURE);
    resource.addProperty("pin_3_name", TR("false choice"));
    resource.addProperty("pin_3_desc",TR("value returned when the boolean input feature is false"));
    resource.addProperty("outparameters",1);
    resource.addProperty("pout_1_type", itFEATURE);
    resource.addProperty("pout_1_name", TR("featurecoverage"));
    resource.addProperty("pout_1_desc",TR("featurecoverage with all features that correspond to the true value in the input having a value"));
    resource.prepare();
    url += "=" + QString::number(resource.id());
    resource.setUrl(url);

    mastercatalog()->addItems({resource});
    return resource.id();
}
<commit_msg>casing<commit_after>#include <QString>
#include <QStringList>
#include <functional>
#include <future>
#include <memory>
#include "kernel.h"
#include "coverage.h"
#include "columndefinition.h"
#include "table.h"
#include "attributerecord.h"
#include "feature.h"
#include "featurecoverage.h"
#include "symboltable.h"
#include "operationExpression.h"
#include "operationmetadata.h"
#include "operation.h"
#include "operationhelper.h"
#include "operationhelperfeatures.h"
#include "commandhandler.h"
#include "featureiterator.h"
#include "ifoperation.h"
#include "iffeature.h"

using namespace Ilwis;
using namespace BaseOperations;

REGISTER_OPERATION(IfFeature)

Ilwis::BaseOperations::IfFeature::IfFeature()
{
}

IfFeature::IfFeature(quint64 metaid, const Ilwis::OperationExpression &expr) : IfOperation(metaid, expr)
{
}

bool IfFeature::execute(ExecutionContext *ctx, SymbolTable &symTable)
{
    if (_prepState == sNOTPREPARED)
        if((_prepState = prepare(ctx, symTable)) != sPREPARED)
            return false;

    SubSetAsyncFunc iffunc = [&](const std::vector<quint32>& subset) -> bool {

        FeatureIterator iterOut(_outputFC);
        FeatureIterator iterIn(_inputFC,subset);
        FeatureIterator iterEnd = iterOut.end();
        while(iterIn != iterEnd) {
            _outputFC->newFeatureFrom(*iterIn);

            ++iterOut;
            ++iterIn;
        }
        return true;

    };

    bool resource = OperationHelperFeatures::execute(ctx, iffunc, _inputFC, _outputFC);

    if ( resource && ctx != 0) {
        QVariant value;
        value.setValue<IFeatureCoverage>(_outputFC);
        ctx->setOutput(symTable,value,_outputFC->name(),itFEATURE,_outputFC->source());
    }
    return true;
}

Ilwis::OperationImplementation *IfFeature::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new IfFeature(metaid, expr);
}

Ilwis::OperationImplementation::State IfFeature::prepare(ExecutionContext *ctx, const SymbolTable &)
{
    QString fc = _expression.parm(0).value();

    if (!_inputFC.prepare(fc)) {
        ERROR2(ERR_COULD_NOT_LOAD_2,fc,"");
        return sPREPAREFAILED;
    }

    OperationHelperFeatures helper;
    IIlwisObject obj = helper.initialize(_inputFC.as<IlwisObject>(), itFEATURE, itENVELOPE | itCOORDSYSTEM) ;
    if ( !obj.isValid()) {
        ERROR2(ERR_INVALID_INIT_FOR_2,"FeatureCoverage",fc);
        return sPREPAREFAILED;
    }
    _outputFC = obj.as<FeatureCoverage>();

//    DataDefinition outputDataDef = findOutputDataDef(_expression);
//    _outputFC->datadef() = outputDataDef;

    return sPREPARED;
}

quint64 IfFeature::createMetadata()
{
    QString url = QString("ilwis://operations/iff");
    Resource resource(QUrl(url), itOPERATIONMETADATA);
    resource.addProperty("namespace","ilwis");
    resource.addProperty("longname","iff");
    resource.addProperty("syntax","iffraster(featurecoverage,outputchoicetrue, outputchoicefalse)");
    resource.addProperty("description","constructs a new coverage based on a boolean selection described by the boolean map. The true pixels are taken from the first input map, the false pixels from the second map");
    resource.addProperty("inparameters","3");
    resource.addProperty("pin_1_type", itFEATURE);
    resource.addProperty("pin_1_name", TR("input featurecoverage"));
    resource.addProperty("pin_1_desc",TR("input featurecoverage with boolean domain"));
    resource.addProperty("pin_2_type", itNUMBER | itSTRING | itBOOL | itFEATURE);
    resource.addProperty("pin_2_name", TR("true choice"));
    resource.addProperty("pin_2_desc",TR("value returned when the boolean input feature is true"));
    resource.addProperty("pin_3_type", itNUMBER | itSTRING | itBOOL | itFEATURE);
    resource.addProperty("pin_3_name", TR("false choice"));
    resource.addProperty("pin_3_desc",TR("value returned when the boolean input feature is false"));
    resource.addProperty("outparameters",1);
    resource.addProperty("pout_1_type", itFEATURE);
    resource.addProperty("pout_1_name", TR("featurecoverage"));
    resource.addProperty("pout_1_desc",TR("featurecoverage with all features that correspond to the true value in the input having a value"));
    resource.prepare();
    url += "=" + QString::number(resource.id());
    resource.setUrl(url);

    mastercatalog()->addItems({resource});
    return resource.id();
}
<|endoftext|>


<commit_before>#ifndef CPPMATH_AABB_INL
#define CPPMATH_AABB_INL

#include "AABB.hpp"
#include "../math.hpp"

namespace geometry
{
    template <class T>
    AABB<T>::AABB() {};

    template <class T>
    AABB<T>::AABB(T x, T y, T w, T h) :
            pos(x, y),
            size(w, h)
    {};

    template <class T>
    AABB<T>::AABB(const Vec2<T>& pos_, const Vec2<T>& size_) :
            pos(pos_),
            size(size_)
    {};

    template <class T>
    void AABB<T>::crop(const AABB<T>& rect)
    {
        if (intersects(rect))
        {
            size += pos; //convert to "range"-rect

            size.x = std::min(size.x, rect.pos.x + rect.size.x);
            size.y = std::min(size.y, rect.pos.y + rect.size.y);

            pos.x = std::max(pos.x, rect.pos.x);
            pos.y = std::max(pos.y, rect.pos.y);

            size -= pos;
        }
        else
        {
            pos = size = Vec2<T>(); //null rect
        }
    };

    template <class T>
    bool AABB<T>::contains(const Vec2<T>& point) const
    {
        return point >= pos && point < pos + size;
    }

    template <class T>
    bool AABB<T>::contains(const AABB<T>& rect) const
    {
        return contains(rect.pos) && contains(rect.pos + rect.size);
    }

    template <class T>
    Intersection<T> AABB<T>::intersect(const AABB<T>& other) const
    {
        T dx = (other.pos.x + other.size.x / 2) - (pos.x + size.x / 2);
        T px = (other.size.x / 2 + size.x / 2) - abs(dx);
        if (px <= 0)
            return Intersection<T>();

        T dy = (other.pos.y + other.size.y / 2) - (pos.y + size.y / 2);
        T py = (other.size.y / 2 + size.y / 2) - abs(dy);
        if (py <= 0)
            return Intersection<T>();

        return Intersection<T>(Vec2<T>(px * math::sign(dx), py * math::sign(dy)));
    };

    template <class T>
    bool AABB<T>::operator!=(const AABB<T>& r) const
    {
        return pos != r.pos || size != r.size;
    }

    template <class T>
    bool AABB<T>::operator==(const AABB<T>& r) const
    {
        return pos == r.pos && size == r.size;
    }

    template <class T>
    template <class T2>
    AABB<T>::operator AABB<T2>() const
    {
        return AABB<T2>(pos, size);
    }
}

#endif
<commit_msg>Fix AABBxAABB check when their x/y difference is 0<commit_after>#ifndef CPPMATH_AABB_INL
#define CPPMATH_AABB_INL

#include "AABB.hpp"
#include "../math.hpp"

namespace geometry
{
    template <class T>
    AABB<T>::AABB() {};

    template <class T>
    AABB<T>::AABB(T x, T y, T w, T h) :
            pos(x, y),
            size(w, h)
    {};

    template <class T>
    AABB<T>::AABB(const Vec2<T>& pos_, const Vec2<T>& size_) :
            pos(pos_),
            size(size_)
    {};

    template <class T>
    void AABB<T>::crop(const AABB<T>& rect)
    {
        if (intersects(rect))
        {
            size += pos; //convert to "range"-rect

            size.x = std::min(size.x, rect.pos.x + rect.size.x);
            size.y = std::min(size.y, rect.pos.y + rect.size.y);

            pos.x = std::max(pos.x, rect.pos.x);
            pos.y = std::max(pos.y, rect.pos.y);

            size -= pos;
        }
        else
        {
            pos = size = Vec2<T>(); //null rect
        }
    };

    template <class T>
    bool AABB<T>::contains(const Vec2<T>& point) const
    {
        return point >= pos && point < pos + size;
    }

    template <class T>
    bool AABB<T>::contains(const AABB<T>& rect) const
    {
        return contains(rect.pos) && contains(rect.pos + rect.size);
    }

    template <class T>
    Intersection<T> AABB<T>::intersect(const AABB<T>& other) const
    {
        // Adapted from http://noonat.github.io/intersect/#aabb-vs-aabb
        T dx = (other.pos.x + other.size.x / 2) - (pos.x + size.x / 2);
        T px = (other.size.x / 2 + size.x / 2) - abs(dx);
        if (px <= 0)
            return Intersection<T>();

        T dy = (other.pos.y + other.size.y / 2) - (pos.y + size.y / 2);
        T py = (other.size.y / 2 + size.y / 2) - abs(dy);
        if (py <= 0)
            return Intersection<T>();

        return Intersection<T>(Vec2<T>(
                    px * (dx < 0 ? -1 : 1), py * (dy < 0 ? -1 : 1)));
    };

    template <class T>
    bool AABB<T>::operator!=(const AABB<T>& r) const
    {
        return pos != r.pos || size != r.size;
    }

    template <class T>
    bool AABB<T>::operator==(const AABB<T>& r) const
    {
        return pos == r.pos && size == r.size;
    }

    template <class T>
    template <class T2>
    AABB<T>::operator AABB<T2>() const
    {
        return AABB<T2>(pos, size);
    }
}

#endif
<|endoftext|>


<commit_before>// mapchange.cpp : Defines the entry point for the DLL application.
//

#include "bzfsAPI.h"
#include "plugin_utils.h"
#include <math.h>
#include <time.h>
#include <fstream>
#include <string>
#include <list>

std::string confFile;
std::string outputFile;
bool matchInProgress = false;

class MapChangerCommands : public bz_CustomSlashCommandHandler
{
public:

  virtual bool SlashCommand ( int playerID, bz_ApiString command, bz_ApiString /*message*/, bz_APIStringList* params )
  {
    if (command == "maplist") {
      std::ifstream confStream(confFile.c_str());
      if (!confStream.fail()) {
        std::string line;

        bz_sendTextMessage(BZ_SERVER,playerID,"Available configurations: ");

        bz_APIStringList* lineList = bz_newStringList();
        while (std::getline(confStream, line))
        {
          lineList->clear();
          lineList->tokenize(line.c_str(), " \t", 2, true);

          if (lineList->size() == 2)
            bz_sendTextMessage(BZ_SERVER,playerID,(std::string(" -  ") + lineList->get(0).c_str()).c_str());
        }
        bz_deleteStringList(lineList);
      }
      return true;
    }

    bz_BasePlayerRecord *player = bz_getPlayerByIndex(playerID);
    if (!player)
      return true;

    if (player->hasPerm("mapchange")) {
      if (!matchInProgress || player->hasPerm(bz_perm_shutdownServer)) {
        if (command == "maprandom") {
          std::ifstream confStream(confFile.c_str());
          std::string line;

          std::vector<std::string> mapnames;
          std::vector<std::string> mapfiles;
          bz_APIStringList* lineList = bz_newStringList();
          while (std::getline(confStream, line))
          {
            lineList->clear();
            lineList->tokenize(line.c_str(), " \t", 2, true);

            if (lineList->size() == 2) {
              mapnames.push_back(lineList->get(0).c_str());
              mapfiles.push_back(lineList->get(1).c_str());
            }
          }

          int i = rand() % mapnames.size();
          std::ofstream oputfStream(outputFile.c_str());
          oputfStream << mapfiles[i] << std::endl;
          oputfStream.close();
          bz_sendTextMessage(BZ_SERVER,BZ_ALLUSERS,(std::string("Server restarting with randomly selected configuration (") + mapnames[i] + "): Requested by " + player->callsign.c_str()).c_str());
          bz_shutdown();

          bz_deleteStringList(lineList);
          bz_freePlayerRecord(player);

          return true;
        }
        if (params->size() != 1) {
          bz_sendTextMessage(BZ_SERVER,playerID,"Usage: /mapchange <confname>");
          bz_freePlayerRecord(player);

          return true;
        }

        bool done = false;
        std::ifstream confStream(confFile.c_str());
        if (!confStream.fail()) {
          std::string line;

          bz_APIStringList* lineList = bz_newStringList();
          while (std::getline(confStream, line))
          {
            lineList->clear();
            lineList->tokenize(line.c_str(), " \t", 2, true);
	    bz_ApiString thisConfName = lineList->get(0); thisConfName.tolower();
	    bz_ApiString requestedConfName = params->get(0); requestedConfName.tolower();
	    if (lineList->size() == 2 && thisConfName == requestedConfName) {
              std::ofstream oputfStream(outputFile.c_str());
              oputfStream << lineList->get(1).c_str() << std::endl;
              oputfStream.close();
              bz_sendTextMessage(BZ_SERVER,BZ_ALLUSERS,(std::string("Server restarting with configuration ") + lineList->get(0).c_str() + ": Requested by " + player->callsign.c_str()).c_str());
              bz_shutdown();
              done = true;
            }
          }

          bz_deleteStringList(lineList);
        }
        if (!done) bz_sendTextMessage(BZ_SERVER,playerID,"The configuration you selected does not exist");
      }
      else {
        bz_sendTextMessage(BZ_SERVER,playerID,"Sorry, you are not allowed to change configurations when a match is in progress");
        bz_sendTextMessage(BZ_SERVER,playerID,"For this malicious activity, you will be kicked");
        bz_kickUser(playerID, "mapchange during match", true);
      }
    }
    else bz_sendTextMessage(BZ_SERVER,playerID,"Sorry, you are not allowed to change configurations on this server");

    bz_freePlayerRecord(player);

    return true;
  }
};

MapChangerCommands mapChanger;

class MapChanger : public bz_Plugin
{
public:
  virtual void Event ( bz_EventData *eventData )
  {
    if (eventData->eventType == bz_eGameEndEvent) matchInProgress = false;
    else if (eventData->eventType == bz_eGameStartEvent) matchInProgress = true;
  }

  virtual const char* Name (){return "Map Change";}
  virtual void Init ( const char* config);
  virtual void Cleanup();
};

BZ_PLUGIN(MapChanger);

void MapChanger::Init ( const char* commandLine )
{
  bz_debugMessage(4,"mapchange plugin loaded");
  PluginConfig config(commandLine);
  if(! config.errors) {
    confFile = config.item("mapchange", "ConfigurationFile");
    outputFile = config.item("mapchange", "OutputFile");
  }
  Register(bz_eGameEndEvent);
  Register(bz_eGameStartEvent);
  bz_registerCustomSlashCommand ( "mapchange", &mapChanger );
  bz_registerCustomSlashCommand ( "maplist", &mapChanger );
  bz_registerCustomSlashCommand ( "maprandom", &mapChanger );
  srand(time(NULL));
}

void MapChanger::Cleanup ( void )
{
  Flush();
  bz_removeCustomSlashCommand ( "maprandom" );
  bz_removeCustomSlashCommand ( "maplist" );
  bz_removeCustomSlashCommand ( "mapchange" );
  bz_debugMessage(4,"mapchange plugin unloaded");
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>Don't allow map change during match. Ever<commit_after>// mapchange.cpp : Defines the entry point for the DLL application.
//

#include "bzfsAPI.h"
#include "plugin_utils.h"
#include <math.h>
#include <time.h>
#include <fstream>
#include <string>
#include <list>

std::string confFile;
std::string outputFile;
bool matchInProgress = false;

class MapChangerCommands : public bz_CustomSlashCommandHandler
{
public:

  virtual bool SlashCommand ( int playerID, bz_ApiString command, bz_ApiString /*message*/, bz_APIStringList* params )
  {
    if (command == "maplist") {
      std::ifstream confStream(confFile.c_str());
      if (!confStream.fail()) {
        std::string line;

        bz_sendTextMessage(BZ_SERVER,playerID,"Available configurations: ");

        bz_APIStringList* lineList = bz_newStringList();
        while (std::getline(confStream, line))
        {
          lineList->clear();
          lineList->tokenize(line.c_str(), " \t", 2, true);

          if (lineList->size() == 2)
            bz_sendTextMessage(BZ_SERVER,playerID,(std::string(" -  ") + lineList->get(0).c_str()).c_str());
        }
        bz_deleteStringList(lineList);
      }
      return true;
    }

    bz_BasePlayerRecord *player = bz_getPlayerByIndex(playerID);
    if (!player)
      return true;

    if (player->hasPerm("mapchange")) {
      if (!matchInProgress) {
        if (command == "maprandom") {
          std::ifstream confStream(confFile.c_str());
          std::string line;

          std::vector<std::string> mapnames;
          std::vector<std::string> mapfiles;
          bz_APIStringList* lineList = bz_newStringList();
          while (std::getline(confStream, line))
          {
            lineList->clear();
            lineList->tokenize(line.c_str(), " \t", 2, true);

            if (lineList->size() == 2) {
              mapnames.push_back(lineList->get(0).c_str());
              mapfiles.push_back(lineList->get(1).c_str());
            }
          }

          int i = rand() % mapnames.size();
          std::ofstream oputfStream(outputFile.c_str());
          oputfStream << mapfiles[i] << std::endl;
          oputfStream.close();
          bz_sendTextMessage(BZ_SERVER,BZ_ALLUSERS,(std::string("Server restarting with randomly selected configuration (") + mapnames[i] + "): Requested by " + player->callsign.c_str()).c_str());
          bz_shutdown();

          bz_deleteStringList(lineList);
          bz_freePlayerRecord(player);

          return true;
        }
        if (params->size() != 1) {
          bz_sendTextMessage(BZ_SERVER,playerID,"Usage: /mapchange <confname>");
          bz_freePlayerRecord(player);

          return true;
        }

        bool done = false;
        std::ifstream confStream(confFile.c_str());
        if (!confStream.fail()) {
          std::string line;

          bz_APIStringList* lineList = bz_newStringList();
          while (std::getline(confStream, line))
          {
            lineList->clear();
            lineList->tokenize(line.c_str(), " \t", 2, true);
	    bz_ApiString thisConfName = lineList->get(0); thisConfName.tolower();
	    bz_ApiString requestedConfName = params->get(0); requestedConfName.tolower();
	    if (lineList->size() == 2 && thisConfName == requestedConfName) {
              std::ofstream oputfStream(outputFile.c_str());
              oputfStream << lineList->get(1).c_str() << std::endl;
              oputfStream.close();
              bz_sendTextMessage(BZ_SERVER,BZ_ALLUSERS,(std::string("Server restarting with configuration ") + lineList->get(0).c_str() + ": Requested by " + player->callsign.c_str()).c_str());
              bz_shutdown();
              done = true;
            }
          }

          bz_deleteStringList(lineList);
        }
        if (!done) bz_sendTextMessage(BZ_SERVER,playerID,"The configuration you selected does not exist");
      }
      else {
        bz_sendTextMessage(BZ_SERVER,playerID,"Sorry, you are not allowed to change configurations when a match is in progress");
        bz_sendTextMessage(BZ_SERVER,playerID,"For this malicious activity, you will be kicked");
        bz_kickUser(playerID, "mapchange during match", true);
      }
    }
    else bz_sendTextMessage(BZ_SERVER,playerID,"Sorry, you are not allowed to change configurations on this server");

    bz_freePlayerRecord(player);

    return true;
  }
};

MapChangerCommands mapChanger;

class MapChanger : public bz_Plugin
{
public:
  virtual void Event ( bz_EventData *eventData )
  {
    if (eventData->eventType == bz_eGameEndEvent) matchInProgress = false;
    else if (eventData->eventType == bz_eGameStartEvent) matchInProgress = true;
  }

  virtual const char* Name (){return "Map Change";}
  virtual void Init ( const char* config);
  virtual void Cleanup();
};

BZ_PLUGIN(MapChanger);

void MapChanger::Init ( const char* commandLine )
{
  bz_debugMessage(4,"mapchange plugin loaded");
  PluginConfig config(commandLine);
  if(! config.errors) {
    confFile = config.item("mapchange", "ConfigurationFile");
    outputFile = config.item("mapchange", "OutputFile");
  }
  Register(bz_eGameEndEvent);
  Register(bz_eGameStartEvent);
  bz_registerCustomSlashCommand ( "mapchange", &mapChanger );
  bz_registerCustomSlashCommand ( "maplist", &mapChanger );
  bz_registerCustomSlashCommand ( "maprandom", &mapChanger );
  srand(time(NULL));
}

void MapChanger::Cleanup ( void )
{
  Flush();
  bz_removeCustomSlashCommand ( "maprandom" );
  bz_removeCustomSlashCommand ( "maplist" );
  bz_removeCustomSlashCommand ( "mapchange" );
  bz_debugMessage(4,"mapchange plugin unloaded");
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/renderer/web_worker_observer.h"

#include "base/lazy_instance.h"
#include "base/threading/thread_local.h"
#include "shell/common/api/electron_bindings.h"
#include "shell/common/gin_helper/event_emitter_caller.h"
#include "shell/common/node_bindings.h"
#include "shell/common/node_includes.h"

namespace electron {

namespace {

static base::LazyInstance<
    base::ThreadLocalPointer<WebWorkerObserver>>::DestructorAtExit lazy_tls =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

// static
WebWorkerObserver* WebWorkerObserver::GetCurrent() {
  WebWorkerObserver* self = lazy_tls.Pointer()->Get();
  return self ? self : new WebWorkerObserver;
}

WebWorkerObserver::WebWorkerObserver()
    : node_bindings_(
          NodeBindings::Create(NodeBindings::BrowserEnvironment::kWorker)),
      electron_bindings_(
          std::make_unique<ElectronBindings>(node_bindings_->uv_loop())) {
  lazy_tls.Pointer()->Set(this);
}

WebWorkerObserver::~WebWorkerObserver() {
  lazy_tls.Pointer()->Set(nullptr);
  node::FreeEnvironment(node_bindings_->uv_env());
  node::FreeIsolateData(node_bindings_->isolate_data());
}

void WebWorkerObserver::WorkerScriptReadyForEvaluation(
    v8::Local<v8::Context> worker_context) {
  v8::Context::Scope context_scope(worker_context);
  auto* isolate = worker_context->GetIsolate();
  v8::MicrotasksScope microtasks_scope(
      isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);

  // Start the embed thread.
  node_bindings_->PrepareMessageLoop();

  // Setup node environment for each window.
  bool initialized = node::InitializeContext(worker_context);
  CHECK(initialized);
  node::Environment* env =
      node_bindings_->CreateEnvironment(worker_context, nullptr);

  // Add Electron extended APIs.
  electron_bindings_->BindTo(env->isolate(), env->process_object());

  // Load everything.
  node_bindings_->LoadEnvironment(env);

  // Make uv loop being wrapped by window context.
  node_bindings_->set_uv_env(env);

  // Give the node loop a run to make sure everything is ready.
  node_bindings_->RunMessageLoop();
}

void WebWorkerObserver::ContextWillDestroy(v8::Local<v8::Context> context) {
  node::Environment* env = node::Environment::GetCurrent(context);
  if (env)
    gin_helper::EmitEvent(env->isolate(), env->process_object(), "exit");

  delete this;
}

}  // namespace electron
<commit_msg>fix: ensure TracingAgent in place for SWs (#31459)<commit_after>// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/renderer/web_worker_observer.h"

#include "base/lazy_instance.h"
#include "base/threading/thread_local.h"
#include "shell/common/api/electron_bindings.h"
#include "shell/common/gin_helper/event_emitter_caller.h"
#include "shell/common/node_bindings.h"
#include "shell/common/node_includes.h"

namespace electron {

namespace {

static base::LazyInstance<
    base::ThreadLocalPointer<WebWorkerObserver>>::DestructorAtExit lazy_tls =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

// static
WebWorkerObserver* WebWorkerObserver::GetCurrent() {
  WebWorkerObserver* self = lazy_tls.Pointer()->Get();
  return self ? self : new WebWorkerObserver;
}

WebWorkerObserver::WebWorkerObserver()
    : node_bindings_(
          NodeBindings::Create(NodeBindings::BrowserEnvironment::kWorker)),
      electron_bindings_(
          std::make_unique<ElectronBindings>(node_bindings_->uv_loop())) {
  lazy_tls.Pointer()->Set(this);
}

WebWorkerObserver::~WebWorkerObserver() {
  lazy_tls.Pointer()->Set(nullptr);
  node::FreeEnvironment(node_bindings_->uv_env());
  node::FreeIsolateData(node_bindings_->isolate_data());
}

void WebWorkerObserver::WorkerScriptReadyForEvaluation(
    v8::Local<v8::Context> worker_context) {
  v8::Context::Scope context_scope(worker_context);
  auto* isolate = worker_context->GetIsolate();
  v8::MicrotasksScope microtasks_scope(
      isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);

  // Start the embed thread.
  node_bindings_->PrepareMessageLoop();

  // Setup node tracing controller.
  if (!node::tracing::TraceEventHelper::GetAgent())
    node::tracing::TraceEventHelper::SetAgent(node::CreateAgent());

  // Setup node environment for each window.
  bool initialized = node::InitializeContext(worker_context);
  CHECK(initialized);
  node::Environment* env =
      node_bindings_->CreateEnvironment(worker_context, nullptr);

  // Add Electron extended APIs.
  electron_bindings_->BindTo(env->isolate(), env->process_object());

  // Load everything.
  node_bindings_->LoadEnvironment(env);

  // Make uv loop being wrapped by window context.
  node_bindings_->set_uv_env(env);

  // Give the node loop a run to make sure everything is ready.
  node_bindings_->RunMessageLoop();
}

void WebWorkerObserver::ContextWillDestroy(v8::Local<v8::Context> context) {
  node::Environment* env = node::Environment::GetCurrent(context);
  if (env)
    gin_helper::EmitEvent(env->isolate(), env->process_object(), "exit");

  delete this;
}

}  // namespace electron
<|endoftext|>


<commit_before>// RUN: llvm-cov show %S/Inputs/deferred-regions.covmapping -instr-profile %S/Inputs/deferred-regions.profdata -show-line-counts-or-regions -dump -path-equivalence=/Users/vk/src/llvm.org-coverage-braces/llvm/test/tools,%S/.. %s 2&>1 > %t.out && FileCheck %s -input-file %t.out && FileCheck %s -input-file %t.out -check-prefix=MARKER

void foo(int x) {
  if (x == 0) {
    return; // CHECK: [[@LINE]]|{{ +}}1|
  }

} // CHECK: [[@LINE]]|{{ +}}1|

void bar() {
  return;

} // CHECK: [[@LINE]]|{{ +}}1|

void for_loop() {
  if (false)
    return; // CHECK: [[@LINE]]|{{ +}}0|

  for (int i = 0; i < 10; ++i) { // CHECK: [[@LINE]]|{{ +}}2|
    if (i % 2 == 0)
      continue; // CHECK: [[@LINE]]|{{ +}}1|

    if (i % 5 == 0)
      break; // CHECK: [[@LINE]]|{{ +}}0|

    int x = i;
    return; // CHECK: [[@LINE]]|{{ +}}1|

  } // CHECK: [[@LINE]]|{{ +}}1|
}

struct Error {};

void while_loop() {
  if (false)
    return; // CHECK: [[@LINE]]|{{ +}}0|

  int x = 0;
  while (++x < 10) { // CHECK: [[@LINE]]|{{ +}}3|
    if (x == 1)
      continue; // CHECK: [[@LINE]]|{{ +}}1|

    while (++x < 4) { // CHECK: [[@LINE]]|{{ +}}1|
      if (x == 3)
        break; // CHECK: [[@LINE]]|{{ +}}1|
               // CHECK: [[@LINE]]|{{ +}}0|
      while (++x < 5) {} // CHECK: [[@LINE]]|{{ +}}0|
    } // CHECK: [[@LINE]]|{{ +}}1|

    if (x == 0)
      throw Error(); // CHECK: [[@LINE]]|{{ +}}0|

    while (++x < 9) { // CHECK: [[@LINE]]|{{ +}}6|
      if (x == 0) // CHECK: [[@LINE]]|{{ +}}5|
        break; // CHECK: [[@LINE]]|{{ +}}0|

    }
  }
}

void gotos() {
  if (false)
    goto out; // CHECK: [[@LINE]]|{{ +}}0|

  return;

out: // CHECK: [[@LINE]]|{{ +}}1|
	return;
}

int main() {
  foo(0);
  foo(1);
  bar();
  for_loop();
  while_loop();
  gotos();
  return 0;
}

// MARKER: Marker at 4:7 = 2
// MARKER-NEXT: Highlighted line 17, 5 -> 11
// MARKER-NEXT: Marker at 17:5 = 0
// MARKER-NEXT: Marker at 19:3 = 1
// MARKER-NEXT: Marker at 19:19 = 2
// MARKER-NEXT: Marker at 19:27 = 1
// MARKER-NEXT: Marker at 21:7 = 1
// MARKER-NEXT: Marker at 23:5 = 1
// MARKER-NEXT: Marker at 23:9 = 1
// MARKER-NEXT: Highlighted line 24, 7 -> 12
// MARKER-NEXT: Marker at 24:7 = 0
// MARKER-NEXT: Highlighted line 36, 5 -> 11
// MARKER-NEXT: Marker at 36:5 = 0
// MARKER-NEXT: Marker at 39:10 = 3
// MARKER-NEXT: Marker at 41:7 = 1
// MARKER-NEXT: Marker at 43:5 = 1
// MARKER-NEXT: Marker at 43:12 = 1
// MARKER-NEXT: Highlighted line 45, 14 -> ?
// MARKER-NEXT: Marker at 45:9 = 1
// MARKER-NEXT: Highlighted line 46, 1 -> ?
// MARKER-NEXT: Highlighted line 47, 1 -> 7
// MARKER-NEXT: Highlighted line 47, 7 -> 14
// MARKER-NEXT: Highlighted line 47, 14 -> 21
// MARKER-NEXT: Highlighted line 47, 21 -> 23
// MARKER-NEXT: Highlighted line 47, 23 -> 25
// MARKER-NEXT: Marker at 47:7 = 0
// MARKER-NEXT: Marker at 47:14 = 0
// MARKER-NEXT: Marker at 47:23 = 0
// MARKER-NEXT: Highlighted line 51, 7 -> 20
// MARKER-NEXT: Marker at 51:7 = 0
// MARKER-NEXT: Marker at 53:5 = 1
// MARKER-NEXT: Marker at 53:12 = 6
// MARKER-NEXT: Highlighted line 55, 9 -> 14
// MARKER-NEXT: Highlighted line 63, 5 -> 13
// MARKER-NEXT: Marker at 63:5 = 0
// MARKER-NEXT: Highlighted line 67, 1 -> ?
// MARKER-NEXT: Highlighted line 68, 1 -> 8
// MARKER-NEXT: Highlighted line 68, 8 -> ?
// MARKER-NEXT: Highlighted line 69, 1 -> 2
<commit_msg>Fixed a typo in llvm-cov/deferred-region.cpp test.<commit_after>// RUN: llvm-cov show %S/Inputs/deferred-regions.covmapping -instr-profile %S/Inputs/deferred-regions.profdata -show-line-counts-or-regions -dump -path-equivalence=/Users/vk/src/llvm.org-coverage-braces/llvm/test/tools,%S/.. %s 2>&1 > %t.out && FileCheck %s -input-file %t.out && FileCheck %s -input-file %t.out -check-prefix=MARKER

void foo(int x) {
  if (x == 0) {
    return; // CHECK: [[@LINE]]|{{ +}}1|
  }

} // CHECK: [[@LINE]]|{{ +}}1|

void bar() {
  return;

} // CHECK: [[@LINE]]|{{ +}}1|

void for_loop() {
  if (false)
    return; // CHECK: [[@LINE]]|{{ +}}0|

  for (int i = 0; i < 10; ++i) { // CHECK: [[@LINE]]|{{ +}}2|
    if (i % 2 == 0)
      continue; // CHECK: [[@LINE]]|{{ +}}1|

    if (i % 5 == 0)
      break; // CHECK: [[@LINE]]|{{ +}}0|

    int x = i;
    return; // CHECK: [[@LINE]]|{{ +}}1|

  } // CHECK: [[@LINE]]|{{ +}}1|
}

struct Error {};

void while_loop() {
  if (false)
    return; // CHECK: [[@LINE]]|{{ +}}0|

  int x = 0;
  while (++x < 10) { // CHECK: [[@LINE]]|{{ +}}3|
    if (x == 1)
      continue; // CHECK: [[@LINE]]|{{ +}}1|

    while (++x < 4) { // CHECK: [[@LINE]]|{{ +}}1|
      if (x == 3)
        break; // CHECK: [[@LINE]]|{{ +}}1|
               // CHECK: [[@LINE]]|{{ +}}0|
      while (++x < 5) {} // CHECK: [[@LINE]]|{{ +}}0|
    } // CHECK: [[@LINE]]|{{ +}}1|

    if (x == 0)
      throw Error(); // CHECK: [[@LINE]]|{{ +}}0|

    while (++x < 9) { // CHECK: [[@LINE]]|{{ +}}6|
      if (x == 0) // CHECK: [[@LINE]]|{{ +}}5|
        break; // CHECK: [[@LINE]]|{{ +}}0|

    }
  }
}

void gotos() {
  if (false)
    goto out; // CHECK: [[@LINE]]|{{ +}}0|

  return;

out: // CHECK: [[@LINE]]|{{ +}}1|
	return;
}

int main() {
  foo(0);
  foo(1);
  bar();
  for_loop();
  while_loop();
  gotos();
  return 0;
}

// MARKER: Marker at 4:7 = 2
// MARKER-NEXT: Highlighted line 17, 5 -> 11
// MARKER-NEXT: Marker at 17:5 = 0
// MARKER-NEXT: Marker at 19:3 = 1
// MARKER-NEXT: Marker at 19:19 = 2
// MARKER-NEXT: Marker at 19:27 = 1
// MARKER-NEXT: Marker at 21:7 = 1
// MARKER-NEXT: Marker at 23:5 = 1
// MARKER-NEXT: Marker at 23:9 = 1
// MARKER-NEXT: Highlighted line 24, 7 -> 12
// MARKER-NEXT: Marker at 24:7 = 0
// MARKER-NEXT: Highlighted line 36, 5 -> 11
// MARKER-NEXT: Marker at 36:5 = 0
// MARKER-NEXT: Marker at 39:10 = 3
// MARKER-NEXT: Marker at 41:7 = 1
// MARKER-NEXT: Marker at 43:5 = 1
// MARKER-NEXT: Marker at 43:12 = 1
// MARKER-NEXT: Highlighted line 45, 14 -> ?
// MARKER-NEXT: Marker at 45:9 = 1
// MARKER-NEXT: Highlighted line 46, 1 -> ?
// MARKER-NEXT: Highlighted line 47, 1 -> 7
// MARKER-NEXT: Highlighted line 47, 7 -> 14
// MARKER-NEXT: Highlighted line 47, 14 -> 21
// MARKER-NEXT: Highlighted line 47, 21 -> 23
// MARKER-NEXT: Highlighted line 47, 23 -> 25
// MARKER-NEXT: Marker at 47:7 = 0
// MARKER-NEXT: Marker at 47:14 = 0
// MARKER-NEXT: Marker at 47:23 = 0
// MARKER-NEXT: Highlighted line 51, 7 -> 20
// MARKER-NEXT: Marker at 51:7 = 0
// MARKER-NEXT: Marker at 53:5 = 1
// MARKER-NEXT: Marker at 53:12 = 6
// MARKER-NEXT: Highlighted line 55, 9 -> 14
// MARKER-NEXT: Highlighted line 63, 5 -> 13
// MARKER-NEXT: Marker at 63:5 = 0
// MARKER-NEXT: Highlighted line 67, 1 -> ?
// MARKER-NEXT: Highlighted line 68, 1 -> 8
// MARKER-NEXT: Highlighted line 68, 8 -> ?
// MARKER-NEXT: Highlighted line 69, 1 -> 2
<|endoftext|>


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

#ifndef MISC_LIB_NUM_UTIL_HPP
#define MISC_LIB_NUM_UTIL_HPP

#include <cctype>
#include <cerrno>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <memory>
#include <utility>

#ifdef __APPLE__
#include <xlocale.h>
#else
#include <locale.h>
#endif

#include "detect.hpp"

BEGIN_MISC_LIB_NAMESPACE_DECL

// in clang 3.6/3.7, generic __builtin_mul_overflow and __builtin_add_overflow is not defined

// add
inline bool add_overflow(unsigned int x, unsigned int y, unsigned int &r) {
  return __builtin_uadd_overflow(x, y, &r);
}

inline bool add_overflow(unsigned long x, unsigned long y, unsigned long &r) {
  return __builtin_uaddl_overflow(x, y, &r);
}

inline bool add_overflow(unsigned long long x, unsigned long long y, unsigned long long &r) {
  return __builtin_uaddll_overflow(x, y, &r);
}

inline bool sadd_overflow(int x, int y, int &r) { return __builtin_sadd_overflow(x, y, &r); }

inline bool sadd_overflow(long x, long y, long &r) { return __builtin_saddl_overflow(x, y, &r); }

inline bool sadd_overflow(long long x, long long y, long long &r) {
  return __builtin_saddll_overflow(x, y, &r);
}

// sub
inline bool ssub_overflow(int x, int y, int &r) { return __builtin_ssub_overflow(x, y, &r); }

inline bool ssub_overflow(long x, long y, long &r) { return __builtin_ssubl_overflow(x, y, &r); }

inline bool ssub_overflow(long long x, long long y, long long &r) {
  return __builtin_ssubll_overflow(x, y, &r);
}

// mul
inline bool mul_overflow(unsigned int x, unsigned int y, unsigned int &r) {
  return __builtin_umul_overflow(x, y, &r);
}

inline bool mul_overflow(unsigned long x, unsigned long y, unsigned long &r) {
  return __builtin_umull_overflow(x, y, &r);
}

inline bool mul_overflow(unsigned long long x, unsigned long long y, unsigned long long &r) {
  return __builtin_umulll_overflow(x, y, &r);
}

inline bool smul_overflow(int x, int y, int &r) { return __builtin_smul_overflow(x, y, &r); }

inline bool smul_overflow(long x, long y, long &r) { return __builtin_smull_overflow(x, y, &r); }

inline bool smul_overflow(long long x, long long y, long long &r) {
  return __builtin_smulll_overflow(x, y, &r);
}

inline unsigned int parseBase(const char *&begin, const char *end) {
  if (begin == end) {
    return 0; // failed
  }

  if (*begin == '0') {
    if (begin + 1 != end) {
      switch (*++begin) {
      case 'x':
      case 'X':
        ++begin;
        return 16;
      case 'o':
      case 'O':
        ++begin;
        return 8;
      }
    }
    return 8;
  }
  return 10;
}

template <typename T>
inline auto dropSign(T v) {
  static_assert(std::is_signed<T>::value, "must be signed type");
  using UT = std::make_unsigned_t<T>;
  return static_cast<UT>(~static_cast<UT>(v) + 1);
}

template <typename UT>
inline auto putSign(UT v) {
  static_assert(std::is_unsigned<UT>::value, "must be unsigned type");
  using T = std::make_signed_t<UT>;
  return static_cast<T>(~v + 1);
}

template <typename U>
inline std::pair<std::make_signed_t<U>, bool> makeSigned(U v, bool negate) {
  static_assert(std::is_unsigned<U>::value, "must be unsigned type");

  using T = std::make_signed_t<U>;
  if (negate) {
    if (v <= dropSign(std::numeric_limits<T>::min())) {
      return {putSign(v), true};
    }
  } else {
    if (v <= static_cast<U>(std::numeric_limits<T>::max())) {
      return {static_cast<T>(v), true};
    }
  }
  return {static_cast<T>(v), false};
}

template <typename T,
          enable_when<std::is_unsigned<T>::value &&
                      (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))> = nullptr>
inline std::pair<T, bool> parseInteger(const char *&begin, const char *end, unsigned int base) {
  if (begin != end && *begin == '+') {
    ++begin;
  }

  if (base == 0) {
    base = parseBase(begin, end);
  }

  errno = 0;
  if (begin == end || base < 2 || base > 36) {
    errno = EINVAL;
    return {0, false};
  }

  T radix = static_cast<T>(base);
  T ret = 0;
  bool status = true;
  do {
    char ch = *begin;
    T v;
    if (ch >= '0' && ch <= '9') {
      v = ch - '0';
    } else if (ch >= 'a' && ch <= 'z') {
      v = 10 + (ch - 'a');
    } else if (ch >= 'A' && ch <= 'Z') {
      v = 10 + (ch - 'A');
    } else {
      errno = EINVAL;
      status = false;
      break;
    }

    if (v >= radix) {
      errno = EINVAL;
      status = false;
      break;
    }

    if (mul_overflow(ret, radix, ret) || // ret = ret * radix
        add_overflow(ret, v, ret)) {     // ret = ret + v
      errno = ERANGE;
      status = false;
      break;
    }
  } while (++begin != end);

  return {ret, status};
}

template <typename T,
          enable_when<std::is_signed<T>::value &&
                      (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))> = nullptr>
inline std::pair<T, bool> parseInteger(const char *&begin, const char *end, unsigned int base) {
  bool sign = false;
  if (begin != end && *begin == '-' && *(begin + 1) != '+') {
    sign = true;
    ++begin;
  }

  using UT = std::make_unsigned_t<T>;
  auto ret = parseInteger<UT>(begin, end, base);
  if (ret.second) {
    return makeSigned(ret.first, sign);
  }
  return {static_cast<T>(ret.first), false};
}

/**
 * for string to number conversion
 * @tparam T
 * @param begin
 * @param end
 * @param base
 * if 0, auto detect radix
 *   if starts with '0x', '0X', parse as hex number
 *   if starts with '0', '0o', '0O', parse as octal number
 * if 8, parse as octal number
 * if 10, parse as decimal number
 * if 16, parse as hex number
 *
 * if starts with '-' and T is signed type, negate number
 * @return
 * if detect overflow, return {0, false}
 */
template <typename T, enable_when<std::is_integral<T>::value> = nullptr>
inline std::pair<T, bool> convertToNum(const char *begin, const char *end, unsigned int base = 0) {
  return parseInteger<T>(begin, end, base);
}

/**
 *
 * @tparam T
 * @param str
 * must be null terminated string
 * @param base
 * @return
 */
template <typename T, enable_when<std::is_integral<T>::value> = nullptr>
inline std::pair<T, bool> convertToNum(const char *str, unsigned int base = 0) {
  return convertToNum<T>(str, str + strlen(str), base);
}

class Locale {
private:
  locale_t value;

public:
  Locale(int mask, const char *locale, locale_t base = nullptr)
      : value(newlocale(mask, locale, base)) {}

  ~Locale() { freelocale(this->value); }

  locale_t get() const { return this->value; }

  void use() const { uselocale(this->value); }
};

inline auto LC_NUMERIC_C = Locale(LC_NUMERIC_MASK, "C");

/**
 * parse double with locale independent way
 * @param str
 * @param skipIllegalChar
 * @return (value, status)
 * if success, status is 0.
 * if out of range, status is 1.
 * if cannot convert, status is -1.
 * if found illegal character, status is -2.
 */
inline std::pair<double, int> convertToDouble(const char *str, bool skipIllegalChar = false) {
  errno = 0;

  // convert to double
  if (std::isspace(*str)) {
    return {0, -1};
  }
  char *end;
  const double value = strtod_l(str, &end, LC_NUMERIC_C.get());
  int status = 0;

  // check error
  if (value == 0 && end == str) {
    status = -1;
  } else if (*end != '\0' && !skipIllegalChar) {
    status = -2;
  } else if (value == 0 && errno == ERANGE) {
    status = 1;
  } else if ((value == HUGE_VAL || value == -HUGE_VAL) && errno == ERANGE) {
    status = 1;
  }
  return {value, status};
}

constexpr bool isDecimal(char ch) { return ch >= '0' && ch <= '9'; }

constexpr bool isOctal(char ch) { return ch >= '0' && ch < '8'; }

constexpr bool isHex(char ch) {
  return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');
}

/**
 * convert hex character to number
 * @param ch
 * @return
 */
constexpr unsigned int hexToNum(char ch) {
  if (ch >= '0' && ch <= '9') {
    return ch - '0';
  } else if (ch >= 'a' && ch <= 'f') {
    return 10 + (ch - 'a');
  } else if (ch >= 'A' && ch <= 'F') {
    return 10 + (ch - 'A');
  }
  return 0;
}

inline int64_t doubleToBits(double d) {
  union {
    int64_t i64;
    double f64;
  } data;

  /**
   * https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Double.html#compare-double-double-
   */
  if (std::isnan(d)) {
    return 0x7ff8000000000000L;
  }
  if (std::isinf(d)) {
    return d > 0 ? 0x7ff0000000000000L : 0xfff0000000000000L;
  }
  data.f64 = d;
  return data.i64;
}

inline int compareByTotalOrder(double x, double y) {
  if (x < y) {
    return -1;
  }
  if (x > y) {
    return 1;
  }

  int64_t xx = doubleToBits(x);
  int64_t yy = doubleToBits(y);
  if (xx == yy) {
    return 0;
  }
  return xx < yy ? -1 : 1;
}

END_MISC_LIB_NAMESPACE_DECL

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

#ifndef MISC_LIB_NUM_UTIL_HPP
#define MISC_LIB_NUM_UTIL_HPP

#include <cctype>
#include <cerrno>
#include <climits>
#include <clocale>
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <memory>
#include <utility>

#ifdef __APPLE__
#include <xlocale.h>
#endif

#include "detect.hpp"

BEGIN_MISC_LIB_NAMESPACE_DECL

// in clang 3.6/3.7, generic __builtin_mul_overflow and __builtin_add_overflow is not defined

// add
inline bool add_overflow(unsigned int x, unsigned int y, unsigned int &r) {
  return __builtin_uadd_overflow(x, y, &r);
}

inline bool add_overflow(unsigned long x, unsigned long y, unsigned long &r) {
  return __builtin_uaddl_overflow(x, y, &r);
}

inline bool add_overflow(unsigned long long x, unsigned long long y, unsigned long long &r) {
  return __builtin_uaddll_overflow(x, y, &r);
}

inline bool sadd_overflow(int x, int y, int &r) { return __builtin_sadd_overflow(x, y, &r); }

inline bool sadd_overflow(long x, long y, long &r) { return __builtin_saddl_overflow(x, y, &r); }

inline bool sadd_overflow(long long x, long long y, long long &r) {
  return __builtin_saddll_overflow(x, y, &r);
}

// sub
inline bool ssub_overflow(int x, int y, int &r) { return __builtin_ssub_overflow(x, y, &r); }

inline bool ssub_overflow(long x, long y, long &r) { return __builtin_ssubl_overflow(x, y, &r); }

inline bool ssub_overflow(long long x, long long y, long long &r) {
  return __builtin_ssubll_overflow(x, y, &r);
}

// mul
inline bool mul_overflow(unsigned int x, unsigned int y, unsigned int &r) {
  return __builtin_umul_overflow(x, y, &r);
}

inline bool mul_overflow(unsigned long x, unsigned long y, unsigned long &r) {
  return __builtin_umull_overflow(x, y, &r);
}

inline bool mul_overflow(unsigned long long x, unsigned long long y, unsigned long long &r) {
  return __builtin_umulll_overflow(x, y, &r);
}

inline bool smul_overflow(int x, int y, int &r) { return __builtin_smul_overflow(x, y, &r); }

inline bool smul_overflow(long x, long y, long &r) { return __builtin_smull_overflow(x, y, &r); }

inline bool smul_overflow(long long x, long long y, long long &r) {
  return __builtin_smulll_overflow(x, y, &r);
}

inline unsigned int parseBase(const char *&begin, const char *end) {
  if (begin == end) {
    return 0; // failed
  }

  if (*begin == '0') {
    if (begin + 1 != end) {
      switch (*++begin) {
      case 'x':
      case 'X':
        ++begin;
        return 16;
      case 'o':
      case 'O':
        ++begin;
        return 8;
      }
    }
    return 8;
  }
  return 10;
}

template <typename T>
inline auto dropSign(T v) {
  static_assert(std::is_signed<T>::value, "must be signed type");
  using UT = std::make_unsigned_t<T>;
  return static_cast<UT>(~static_cast<UT>(v) + 1);
}

template <typename UT>
inline auto putSign(UT v) {
  static_assert(std::is_unsigned<UT>::value, "must be unsigned type");
  using T = std::make_signed_t<UT>;
  return static_cast<T>(~v + 1);
}

template <typename U>
inline std::pair<std::make_signed_t<U>, bool> makeSigned(U v, bool negate) {
  static_assert(std::is_unsigned<U>::value, "must be unsigned type");

  using T = std::make_signed_t<U>;
  if (negate) {
    if (v <= dropSign(std::numeric_limits<T>::min())) {
      return {putSign(v), true};
    }
  } else {
    if (v <= static_cast<U>(std::numeric_limits<T>::max())) {
      return {static_cast<T>(v), true};
    }
  }
  return {static_cast<T>(v), false};
}

template <typename T,
          enable_when<std::is_unsigned<T>::value &&
                      (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))> = nullptr>
inline std::pair<T, bool> parseInteger(const char *&begin, const char *end, unsigned int base) {
  if (begin != end && *begin == '+') {
    ++begin;
  }

  if (base == 0) {
    base = parseBase(begin, end);
  }

  errno = 0;
  if (begin == end || base < 2 || base > 36) {
    errno = EINVAL;
    return {0, false};
  }

  T radix = static_cast<T>(base);
  T ret = 0;
  bool status = true;
  do {
    char ch = *begin;
    T v;
    if (ch >= '0' && ch <= '9') {
      v = ch - '0';
    } else if (ch >= 'a' && ch <= 'z') {
      v = 10 + (ch - 'a');
    } else if (ch >= 'A' && ch <= 'Z') {
      v = 10 + (ch - 'A');
    } else {
      errno = EINVAL;
      status = false;
      break;
    }

    if (v >= radix) {
      errno = EINVAL;
      status = false;
      break;
    }

    if (mul_overflow(ret, radix, ret) || // ret = ret * radix
        add_overflow(ret, v, ret)) {     // ret = ret + v
      errno = ERANGE;
      status = false;
      break;
    }
  } while (++begin != end);

  return {ret, status};
}

template <typename T,
          enable_when<std::is_signed<T>::value &&
                      (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))> = nullptr>
inline std::pair<T, bool> parseInteger(const char *&begin, const char *end, unsigned int base) {
  bool sign = false;
  if (begin != end && *begin == '-' && *(begin + 1) != '+') {
    sign = true;
    ++begin;
  }

  using UT = std::make_unsigned_t<T>;
  auto ret = parseInteger<UT>(begin, end, base);
  if (ret.second) {
    return makeSigned(ret.first, sign);
  }
  return {static_cast<T>(ret.first), false};
}

/**
 * for string to number conversion
 * @tparam T
 * @param begin
 * @param end
 * @param base
 * if 0, auto detect radix
 *   if starts with '0x', '0X', parse as hex number
 *   if starts with '0', '0o', '0O', parse as octal number
 * if 8, parse as octal number
 * if 10, parse as decimal number
 * if 16, parse as hex number
 *
 * if starts with '-' and T is signed type, negate number
 * @return
 * if detect overflow, return {0, false}
 */
template <typename T, enable_when<std::is_integral<T>::value> = nullptr>
inline std::pair<T, bool> convertToNum(const char *begin, const char *end, unsigned int base = 0) {
  return parseInteger<T>(begin, end, base);
}

/**
 *
 * @tparam T
 * @param str
 * must be null terminated string
 * @param base
 * @return
 */
template <typename T, enable_when<std::is_integral<T>::value> = nullptr>
inline std::pair<T, bool> convertToNum(const char *str, unsigned int base = 0) {
  return convertToNum<T>(str, str + strlen(str), base);
}

class Locale {
private:
  locale_t value;

public:
  Locale(int mask, const char *locale, locale_t base = nullptr)
      : value(newlocale(mask, locale, base)) {}

  ~Locale() { freelocale(this->value); }

  locale_t get() const { return this->value; }

  void use() const { uselocale(this->value); }
};

inline auto LC_NUMERIC_C = Locale(LC_NUMERIC_MASK, "C");

/**
 * parse double with locale independent way
 * @param str
 * @param skipIllegalChar
 * @return (value, status)
 * if success, status is 0.
 * if out of range, status is 1.
 * if cannot convert, status is -1.
 * if found illegal character, status is -2.
 */
inline std::pair<double, int> convertToDouble(const char *str, bool skipIllegalChar = false) {
  errno = 0;

  // convert to double
  if (std::isspace(*str)) {
    return {0, -1};
  }
  char *end;
  const double value = strtod_l(str, &end, LC_NUMERIC_C.get());
  int status = 0;

  // check error
  if (value == 0 && end == str) {
    status = -1;
  } else if (*end != '\0' && !skipIllegalChar) {
    status = -2;
  } else if (value == 0 && errno == ERANGE) {
    status = 1;
  } else if ((value == HUGE_VAL || value == -HUGE_VAL) && errno == ERANGE) {
    status = 1;
  }
  return {value, status};
}

constexpr bool isDecimal(char ch) { return ch >= '0' && ch <= '9'; }

constexpr bool isOctal(char ch) { return ch >= '0' && ch < '8'; }

constexpr bool isHex(char ch) {
  return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');
}

/**
 * convert hex character to number
 * @param ch
 * @return
 */
constexpr unsigned int hexToNum(char ch) {
  if (ch >= '0' && ch <= '9') {
    return ch - '0';
  } else if (ch >= 'a' && ch <= 'f') {
    return 10 + (ch - 'a');
  } else if (ch >= 'A' && ch <= 'F') {
    return 10 + (ch - 'A');
  }
  return 0;
}

inline int64_t doubleToBits(double d) {
  union {
    int64_t i64;
    double f64;
  } data;

  /**
   * https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Double.html#compare-double-double-
   */
  if (std::isnan(d)) {
    return 0x7ff8000000000000L;
  }
  if (std::isinf(d)) {
    return d > 0 ? 0x7ff0000000000000L : 0xfff0000000000000L;
  }
  data.f64 = d;
  return data.i64;
}

inline int compareByTotalOrder(double x, double y) {
  if (x < y) {
    return -1;
  }
  if (x > y) {
    return 1;
  }

  int64_t xx = doubleToBits(x);
  int64_t yy = doubleToBits(y);
  if (xx == yy) {
    return 0;
  }
  return xx < yy ? -1 : 1;
}

END_MISC_LIB_NAMESPACE_DECL

#endif // MISC_LIB_NUM_UTIL_HPP
<|endoftext|>