<commit_before> // $Id$

 /**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * All rights reserved.                                                   *
 *                                                                        *
 * Primary Authors: Oystein Djuvsland                                     *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliHLTEMCALDigitMakerComponent.h"
#include "AliHLTCaloDigitMaker.h"
#include "AliHLTCaloDigitDataStruct.h"
#include "AliHLTCaloChannelDataHeaderStruct.h"
#include "AliHLTCaloChannelDataStruct.h"
#include "AliHLTEMCALMapper.h"
#include "AliHLTEMCALDefinitions.h"
#include "AliCaloCalibPedestal.h"
#include "AliEMCALCalibData.h"
#include "AliCDBEntry.h"
#include "AliCDBPath.h"
#include "AliCDBManager.h"
#include "TFile.h"
#include <sys/stat.h>
#include <sys/types.h>

//#include "AliHLTEMCALConstant.h"
#include "AliHLTCaloConstants.h"

using EMCAL::NZROWSMOD;
using EMCAL::NXCOLUMNSMOD;
using CALO::HGLGFACTOR;

/**
 * @file   AliHLTEMCALDigitMakerComponent.cxx
 * @author Oystein Djuvsland
 * @date
 * @brief  A digit maker component for EMCAL HLT
*/

// see below for class documentation
// or
// refer to README to build package
// or
// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt

ClassImp(AliHLTEMCALDigitMakerComponent)

AliHLTEMCALDigitMakerComponent gAliHLTEMCALDigitMakerComponent;

AliHLTEMCALDigitMakerComponent::AliHLTEMCALDigitMakerComponent() :
  AliHLTCaloProcessor(),
  //  AliHLTCaloConstantsHandler("EMCAL"),
  fDigitMakerPtr(0),
  fDigitContainerPtr(0),
  fPedestalData(0),
  fCalibData(0),
  fBCMInitialised(true),
  fGainsInitialised(true)
{

  //see header file for documentation
}

AliHLTEMCALDigitMakerComponent::~AliHLTEMCALDigitMakerComponent()
{
  //see header file for documentation
}

int
AliHLTEMCALDigitMakerComponent::Deinit()
{
  //see header file for documentation
  if(fDigitMakerPtr)
    {
      delete fDigitMakerPtr;
      fDigitMakerPtr = 0;
    }
  return 0;
}

const char*
AliHLTEMCALDigitMakerComponent::GetComponentID()
{
  //see header file for documentation
  return "EmcalDigitMaker";
}

void
AliHLTEMCALDigitMakerComponent::GetInputDataTypes(vector<AliHLTComponentDataType>& list)
{
  //see header file for documentation
  list.clear();
  list.push_back(AliHLTEMCALDefinitions::fgkChannelDataType);
}

AliHLTComponentDataType
AliHLTEMCALDigitMakerComponent::GetOutputDataType()
{
  //see header file for documentation
//  return AliHLTCaloDefinitions::fgkDigitDataType|kAliHLTDataOriginEMCAL;
  return AliHLTEMCALDefinitions::fgkDigitDataType;
}

void
AliHLTEMCALDigitMakerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
{
  //see header file for documentation
  constBase = 0;
  inputMultiplier = (float)sizeof(AliHLTCaloDigitDataStruct)/sizeof(AliHLTCaloChannelDataStruct) + 1;
}

int
AliHLTEMCALDigitMakerComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks,
					AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size,
					std::vector<AliHLTComponentBlockData>& outputBlocks)
{
  //see header file for documentation
  UInt_t offset           = 0;
  UInt_t mysize           = 0;
  Int_t digitCount        = 0;
  Int_t ret               = 0;

  const AliHLTComponentBlockData* iter = 0;
  unsigned long ndx;

  UInt_t specification = 0;
  AliHLTCaloChannelDataHeaderStruct* tmpChannelData = 0;

  //  fDigitMakerPtr->SetDigitHeaderPtr(reinterpret_cast<AliHLTCaloDigitHeaderStruct*>(outputPtr));

  fDigitMakerPtr->SetDigitDataPtr(reinterpret_cast<AliHLTCaloDigitDataStruct*>(outputPtr));

  for( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
    {
      iter = blocks+ndx;

      if(iter->fDataType != AliHLTEMCALDefinitions::fgkChannelDataType)
	{
	  continue;
	}

      Int_t module = 0;

      if(!fBCMInitialised)
	{
	  AliHLTEMCALMapper mapper(iter->fSpecification);
	  module = mapper.GetModuleFromSpec(iter->fSpecification);

	  if (module>=0) {

	    for(Int_t x = 0; x < NXCOLUMNSMOD ; x++) // PTH
	      for(Int_t z = 0; z <  NZROWSMOD ; z++) // PTH
        // FR
		fDigitMakerPtr->SetBadChannel(x, z, fPedestalData->IsBadChannel(module, z, x));
	    //delete fBadChannelMap;
	    fBCMInitialised = true;
	  }
	  else
	    HLTError("Error setting pedestal with module value of %d", module);

	}

      if(!fGainsInitialised)
	{

	  AliHLTEMCALMapper mapper(iter->fSpecification);
	  module = mapper.GetModuleFromSpec(iter->fSpecification);

	    if (module>=0) {

	      for(Int_t x = 0; x < NXCOLUMNSMOD; x++)   //PTH
		for(Int_t z = 0; z < NZROWSMOD; z++)   //PTH
		  // FR setting gains
		  fDigitMakerPtr->SetGain(x, z, HGLGFACTOR, fCalibData->GetADCchannel(module, z, x));

	      fGainsInitialised = true;
	    }
	    else
	      HLTError("Error setting gains with module value of %d", module);
	}

      specification |= iter->fSpecification;
      tmpChannelData = reinterpret_cast<AliHLTCaloChannelDataHeaderStruct*>(iter->fPtr);

      ret = fDigitMakerPtr->MakeDigits(tmpChannelData, size-(digitCount*sizeof(AliHLTCaloDigitDataStruct)));

      if(ret == -1)
	{
	  HLTError("Trying to write over buffer size");
	  return -ENOBUFS;
	}
      digitCount += ret;
    }

  mysize += digitCount*sizeof(AliHLTCaloDigitDataStruct);

  HLTDebug("# of digits: %d, used memory size: %d, available size: %d", digitCount, mysize, size);

  if(mysize > 0)
    {
      AliHLTComponentBlockData bd;
      FillBlockData( bd );
      bd.fOffset = offset;
      bd.fSize = mysize;
      bd.fDataType = AliHLTEMCALDefinitions::fgkDigitDataType;
      bd.fSpecification = specification;
      outputBlocks.push_back(bd);
    }

  fDigitMakerPtr->Reset();

  size = mysize;

  return 0;
}

int
AliHLTEMCALDigitMakerComponent::DoInit(int argc, const char** argv )
{
  //see header file for documentation

  fDigitMakerPtr = new AliHLTCaloDigitMaker("EMCAL");

  AliHLTCaloMapper *mapper = new AliHLTEMCALMapper(2);
  fDigitMakerPtr->SetMapper(mapper);

  for(int i = 0; i < argc; i++)
    {
      if(!strcmp("-lowgainfactor", argv[i]))
	{
	  fDigitMakerPtr->SetGlobalLowGainFactor(atof(argv[i+1]));
	}
      if(!strcmp("-highgainfactor", argv[i]))
	{
	  fDigitMakerPtr->SetGlobalHighGainFactor(atof(argv[i+1]));
	}

    }

  if (GetBCMFromCDB())
    return -1;

  if (GetGainsFromCDB())
    return -1;

  //GetBCMFromCDB();
  //fDigitMakerPtr->SetDigitThreshold(2);

  return 0;
}

int AliHLTEMCALDigitMakerComponent::GetBCMFromCDB()
{
   // See header file for class documentation
  fBCMInitialised = false;
  //   HLTInfo("Getting bad channel map...");
  AliCDBPath path("EMCAL","Calib","Pedestals");
  if(path.GetPath())
    {
      //      HLTInfo("configure from entry %s", path.GetPath());
      AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
	if (pEntry)
	{
	    fPedestalData = (AliCaloCalibPedestal*)pEntry->GetObject();
	}
      else
	{
//	    HLTError("can not fetch object \"%s\" from CDB", path);
	    return -1;
	}
    }
   if(!fPedestalData)
   {
	return -1;
   }

   return 0;
}

int AliHLTEMCALDigitMakerComponent::GetGainsFromCDB()
{
   // See header file for class documentation
  fGainsInitialised = false;
  //  HLTInfo("Getting bad channel map...");

  AliCDBPath path("EMCAL","Calib","Data");
  if(path.GetPath())
    {
      //      HLTInfo("configure from entry %s", path.GetPath());
      AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
	if (pEntry)
	{
	    fCalibData = (AliEMCALCalibData*)pEntry->GetObject();
	}
      else
	{
//	    HLTError("can not fetch object \"%s\" from CDB", path);
	    return -1;
	}
    }
   if(!fCalibData) return -1;
   return 0;
}

AliHLTComponent*
AliHLTEMCALDigitMakerComponent::Spawn()
{
  //see header file for documentation
  return new AliHLTEMCALDigitMakerComponent();
}
<commit_msg>added proper handling of EMCAL calibration events<commit_after> // $Id$

 /**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * All rights reserved.                                                   *
 *                                                                        *
 * Primary Authors: Oystein Djuvsland                                     *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/
#include "AliHLTEMCALDigitMakerComponent.h"
#include "AliHLTCaloDigitMaker.h"
#include "AliHLTCaloDigitDataStruct.h"
#include "AliHLTCaloChannelDataHeaderStruct.h"
#include "AliHLTCaloChannelDataStruct.h"
#include "AliHLTEMCALMapper.h"
#include "AliHLTEMCALDefinitions.h"
#include "AliCaloCalibPedestal.h"
#include "AliEMCALCalibData.h"
#include "AliCDBEntry.h"
#include "AliCDBPath.h"
#include "AliCDBManager.h"
#include "AliRawDataHeader.h"
#include "TFile.h"
#include <sys/stat.h>
#include <sys/types.h>

//#include "AliHLTEMCALConstant.h"
#include "AliHLTCaloConstants.h"

using EMCAL::NZROWSMOD;
using EMCAL::NXCOLUMNSMOD;
using CALO::HGLGFACTOR;

/**
 * @file   AliHLTEMCALDigitMakerComponent.cxx
 * @author Oystein Djuvsland
 * @date
 * @brief  A digit maker component for EMCAL HLT
*/

// see below for class documentation
// or
// refer to README to build package
// or
// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt

ClassImp(AliHLTEMCALDigitMakerComponent)

AliHLTEMCALDigitMakerComponent gAliHLTEMCALDigitMakerComponent;

AliHLTEMCALDigitMakerComponent::AliHLTEMCALDigitMakerComponent() :
  AliHLTCaloProcessor(),
  //  AliHLTCaloConstantsHandler("EMCAL"),
  fDigitMakerPtr(0),
  fDigitContainerPtr(0),
  fPedestalData(0),
  fCalibData(0),
  fBCMInitialised(true),
  fGainsInitialised(true)
{

  //see header file for documentation
}

AliHLTEMCALDigitMakerComponent::~AliHLTEMCALDigitMakerComponent()
{
  //see header file for documentation
}

int
AliHLTEMCALDigitMakerComponent::Deinit()
{
  //see header file for documentation
  if(fDigitMakerPtr)
    {
      delete fDigitMakerPtr;
      fDigitMakerPtr = 0;
    }
  return 0;
}

const char*
AliHLTEMCALDigitMakerComponent::GetComponentID()
{
  //see header file for documentation
  return "EmcalDigitMaker";
}

void
AliHLTEMCALDigitMakerComponent::GetInputDataTypes(vector<AliHLTComponentDataType>& list)
{
  //see header file for documentation
  list.clear();
  list.push_back(AliHLTEMCALDefinitions::fgkChannelDataType);
}

AliHLTComponentDataType
AliHLTEMCALDigitMakerComponent::GetOutputDataType()
{
  //see header file for documentation
//  return AliHLTCaloDefinitions::fgkDigitDataType|kAliHLTDataOriginEMCAL;
  return AliHLTEMCALDefinitions::fgkDigitDataType;
}

void
AliHLTEMCALDigitMakerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
{
  //see header file for documentation
  constBase = 0;
  inputMultiplier = (float)sizeof(AliHLTCaloDigitDataStruct)/sizeof(AliHLTCaloChannelDataStruct) + 1;
}

int
AliHLTEMCALDigitMakerComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks,
					AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size,
					std::vector<AliHLTComponentBlockData>& outputBlocks)
{

	//patch in order to skip calib events
  const AliRawDataHeader* cdh = NULL;
  ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true);
	AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
	if(triggerMask == 0) return 0;

  //see header file for documentation
  UInt_t offset           = 0;
  UInt_t mysize           = 0;
  Int_t digitCount        = 0;
  Int_t ret               = 0;

  const AliHLTComponentBlockData* iter = 0;
  unsigned long ndx;

  UInt_t specification = 0;
  AliHLTCaloChannelDataHeaderStruct* tmpChannelData = 0;

  //  fDigitMakerPtr->SetDigitHeaderPtr(reinterpret_cast<AliHLTCaloDigitHeaderStruct*>(outputPtr));

  fDigitMakerPtr->SetDigitDataPtr(reinterpret_cast<AliHLTCaloDigitDataStruct*>(outputPtr));

  for( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
    {
      iter = blocks+ndx;

      if(iter->fDataType != AliHLTEMCALDefinitions::fgkChannelDataType)
	{
	  continue;
	}

      Int_t module = 0;

      if(!fBCMInitialised)
	{
	  AliHLTEMCALMapper mapper(iter->fSpecification);
	  module = mapper.GetModuleFromSpec(iter->fSpecification);

	  if (module>=0) {

	    for(Int_t x = 0; x < NXCOLUMNSMOD ; x++) // PTH
	      for(Int_t z = 0; z <  NZROWSMOD ; z++) // PTH
        // FR
		fDigitMakerPtr->SetBadChannel(x, z, fPedestalData->IsBadChannel(module, z, x));
	    //delete fBadChannelMap;
	    fBCMInitialised = true;
	  }
	  else
	    HLTError("Error setting pedestal with module value of %d", module);

	}

      if(!fGainsInitialised)
	{

	  AliHLTEMCALMapper mapper(iter->fSpecification);
	  module = mapper.GetModuleFromSpec(iter->fSpecification);

	    if (module>=0) {

	      for(Int_t x = 0; x < NXCOLUMNSMOD; x++)   //PTH
		for(Int_t z = 0; z < NZROWSMOD; z++)   //PTH
		  // FR setting gains
		  fDigitMakerPtr->SetGain(x, z, HGLGFACTOR, fCalibData->GetADCchannel(module, z, x));

	      fGainsInitialised = true;
	    }
	    else
	      HLTError("Error setting gains with module value of %d", module);
	}

      specification |= iter->fSpecification;
      tmpChannelData = reinterpret_cast<AliHLTCaloChannelDataHeaderStruct*>(iter->fPtr);

      ret = fDigitMakerPtr->MakeDigits(tmpChannelData, size-(digitCount*sizeof(AliHLTCaloDigitDataStruct)));

      if(ret == -1)
	{
	  HLTError("Trying to write over buffer size");
	  return -ENOBUFS;
	}
      digitCount += ret;
    }

  mysize += digitCount*sizeof(AliHLTCaloDigitDataStruct);

  HLTDebug("# of digits: %d, used memory size: %d, available size: %d", digitCount, mysize, size);

  if(mysize > 0)
    {
      AliHLTComponentBlockData bd;
      FillBlockData( bd );
      bd.fOffset = offset;
      bd.fSize = mysize;
      bd.fDataType = AliHLTEMCALDefinitions::fgkDigitDataType;
      bd.fSpecification = specification;
      outputBlocks.push_back(bd);
    }

  fDigitMakerPtr->Reset();

  size = mysize;

  return 0;
}

int
AliHLTEMCALDigitMakerComponent::DoInit(int argc, const char** argv )
{
  //see header file for documentation

  fDigitMakerPtr = new AliHLTCaloDigitMaker("EMCAL");

  AliHLTCaloMapper *mapper = new AliHLTEMCALMapper(2);
  fDigitMakerPtr->SetMapper(mapper);

  for(int i = 0; i < argc; i++)
    {
      if(!strcmp("-lowgainfactor", argv[i]))
	{
	  fDigitMakerPtr->SetGlobalLowGainFactor(atof(argv[i+1]));
	}
      if(!strcmp("-highgainfactor", argv[i]))
	{
	  fDigitMakerPtr->SetGlobalHighGainFactor(atof(argv[i+1]));
	}

    }

  if (GetBCMFromCDB())
    return -1;

  if (GetGainsFromCDB())
    return -1;

  //GetBCMFromCDB();
  //fDigitMakerPtr->SetDigitThreshold(2);

  return 0;
}

int AliHLTEMCALDigitMakerComponent::GetBCMFromCDB()
{
   // See header file for class documentation
  fBCMInitialised = false;
  //   HLTInfo("Getting bad channel map...");
  AliCDBPath path("EMCAL","Calib","Pedestals");
  if(path.GetPath())
    {
      //      HLTInfo("configure from entry %s", path.GetPath());
      AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
	if (pEntry)
	{
	    fPedestalData = (AliCaloCalibPedestal*)pEntry->GetObject();
	}
      else
	{
//	    HLTError("can not fetch object \"%s\" from CDB", path);
	    return -1;
	}
    }
   if(!fPedestalData)
   {
	return -1;
   }

   return 0;
}

int AliHLTEMCALDigitMakerComponent::GetGainsFromCDB()
{
   // See header file for class documentation
  fGainsInitialised = false;
  //  HLTInfo("Getting bad channel map...");

  AliCDBPath path("EMCAL","Calib","Data");
  if(path.GetPath())
    {
      //      HLTInfo("configure from entry %s", path.GetPath());
      AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
	if (pEntry)
	{
	    fCalibData = (AliEMCALCalibData*)pEntry->GetObject();
	}
      else
	{
//	    HLTError("can not fetch object \"%s\" from CDB", path);
	    return -1;
	}
    }
   if(!fCalibData) return -1;
   return 0;
}

AliHLTComponent*
AliHLTEMCALDigitMakerComponent::Spawn()
{
  //see header file for documentation
  return new AliHLTEMCALDigitMakerComponent();
}
<|endoftext|>


<commit_before>#ifndef SOLAIRE_HEX_ISTREAM_HPP
#define SOLAIRE_HEX_ISTREAM_HPP

//Copyright 2015 Adam Smith
//
//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.

// Contact :
// Email             : solairelibrary@mail.com
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

/*!
	\file ComtaomerIStream.hpp
	\brief
	\author
	Created			: Adam Smith
	Last modified	: Adam Smith
	\date
	Created			: 20th November 2015
	Last Modified	: 12th January 2016
*/

#include "Solaire/Core/IStream.hpp"
#include "Solaire/Core/Container.hpp"
#include "Solaire/Core/Maths.hpp"

namespace Solaire {

	class HexToBinIStream : public IStream {
    private:
        IStream& mStream;
    private:
        uint8_t readByte() throw() {
            HexChar buffer[2];
            mStream >> buffer[0];
            if(mStream.end()) {
                buffer[1] = '0';
            }else {
                mStream >> buffer[1];
            }
            return hexToBin8(buffer);
        }

        // Inherited from IStream

        uint8_t SOLAIRE_EXPORT_CALL readU8() throw() override {
            return readByte();
        }

        uint16_t SOLAIRE_EXPORT_CALL readU16() throw() override {
            return combine16(
                readByte(),
                readByte()
            );
        }

        uint32_t SOLAIRE_EXPORT_CALL readU32() throw() override {
            return combine32(
                readByte(),
                readByte(),
                readByte(),
                readByte()
            );
        }

        uint64_t SOLAIRE_EXPORT_CALL readU64() throw() override {
            return combine64(
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte()
            );
        }

        int8_t SOLAIRE_EXPORT_CALL readI8() throw() override {
            return signCast(readByte());
        }

        int16_t SOLAIRE_EXPORT_CALL readI16() throw() override {
            return signCast(combine16(
                readByte(),
                readByte()
            ));
        }

        int32_t SOLAIRE_EXPORT_CALL readI32() throw() override {
            return signCast(combine32(
                readByte(),
                readByte(),
                readByte(),
                readByte()
            ));

        }

        int64_t SOLAIRE_EXPORT_CALL readI64() throw() override {
            return signCast(combine64(
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte()
            ));
        }

        float SOLAIRE_EXPORT_CALL readF() throw() override {
            //! \todo Optimise readF
            float tmp;
            read(&tmp, sizeof(float));
            return tmp;
        }

        double SOLAIRE_EXPORT_CALL readD() throw() override {
            //! \todo Optimise readD
            double tmp;
            read(&tmp, sizeof(double));
            return tmp;
        }

        char SOLAIRE_EXPORT_CALL readC() throw() override {
            return static_cast<char>(readByte());
        }

    public:
        HexToBinIStream(IStream& aStream) :
            mStream(aStream)
        {}

        SOLAIRE_EXPORT_CALL ~HexToBinIStream() {

        }

        // Inherited from IStream

        void SOLAIRE_EXPORT_CALL read(void* const aAddress, const uint32_t aBytes) throw() override {
            uint8_t* const ptr = static_cast<uint8_t*>(aAddress);
            for(uint32_t i = 0; i < aBytes; ++i) ptr[i] = readByte();
        }

        bool SOLAIRE_EXPORT_CALL isOffsetable() const throw() override {
            return mStream.isOffsetable();
        }

        int32_t SOLAIRE_EXPORT_CALL getOffset() const throw() override {
            return mStream.getOffset();
        }

        bool SOLAIRE_EXPORT_CALL setOffset(const int32_t aOffset) throw() override {
            return mStream.setOffset(aOffset);
        }

        bool SOLAIRE_EXPORT_CALL end() const throw() override {
            return mStream.end();
        }

    };

    class BinToHexIStream : public IStream {
    private:
        IStream& mStream;
        HexChar mBuffer;
        bool mBufferSet;
    private:
        uint8_t readByte() throw() {
            if(mBufferSet) {
                mBufferSet = false;
                return mBuffer;
            }

            HexChar buf[2];
            uint8_t byte;
            mStream >> byte;
            bin8ToHex(byte, buf);
            mBufferSet = true;
            mBuffer = buf[1];
            return buf[0];
        }

        // Inherited from IStream

        uint8_t SOLAIRE_EXPORT_CALL readU8() throw() override {
            return readByte();
        }

        uint16_t SOLAIRE_EXPORT_CALL readU16() throw() override {
            return combine16(
                readByte(),
                readByte()
            );
        }

        uint32_t SOLAIRE_EXPORT_CALL readU32() throw() override {
            return combine32(
                readByte(),
                readByte(),
                readByte(),
                readByte()
            );
        }

        uint64_t SOLAIRE_EXPORT_CALL readU64() throw() override {
            return combine64(
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte()
            );
        }

        int8_t SOLAIRE_EXPORT_CALL readI8() throw() override {
            return signCast(readByte());
        }

        int16_t SOLAIRE_EXPORT_CALL readI16() throw() override {
            return signCast(combine16(
                readByte(),
                readByte()
            ));
        }

        int32_t SOLAIRE_EXPORT_CALL readI32() throw() override {
            return signCast(combine32(
                readByte(),
                readByte(),
                readByte(),
                readByte()
            ));
        }

        int64_t SOLAIRE_EXPORT_CALL readI64() throw() override {
            return signCast(combine64(
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte()
            ));
        }

        float SOLAIRE_EXPORT_CALL readF() throw() override {
            float value;
            read(&value, sizeof(float));
            return value;
        }

        double SOLAIRE_EXPORT_CALL readD() throw() override {
            double value;
            read(&value, sizeof(double));
            return value;
        }

        char SOLAIRE_EXPORT_CALL readC() throw() override {
            return static_cast<char>(readByte());
        }

    public:
        BinToHexIStream(IStream& aStream) :
            mStream(aStream),
            mBufferSet(false)
        {}

        SOLAIRE_EXPORT_CALL ~BinToHexIStream() {
            //! \todo Handle trailing byte
        }

        // Inherited from IStream

        void SOLAIRE_EXPORT_CALL read(void* const aAddress, const uint32_t aBytes) throw() override {
            uint8_t* const ptr = static_cast<uint8_t*>(aAddress);
            for(uint32_t i = 0; i < aBytes; ++i) {
                ptr[i] = readByte();
            }
        }

        bool SOLAIRE_EXPORT_CALL isOffsetable() const throw() override {
            return mStream.isOffsetable();
        }

        int32_t SOLAIRE_EXPORT_CALL getOffset() const throw() override {
            return mStream.getOffset();
        }

        bool SOLAIRE_EXPORT_CALL setOffset(const int32_t aOffset) throw() override {
            return mStream.setOffset(aOffset);
        }

        bool SOLAIRE_EXPORT_CALL end() const throw() override {
            return mStream.end();
        }

    };

}

#endif
<commit_msg>Fixed file description<commit_after>#ifndef SOLAIRE_HEX_ISTREAM_HPP
#define SOLAIRE_HEX_ISTREAM_HPP

//Copyright 2015 Adam Smith
//
//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.

// Contact :
// Email             : solairelibrary@mail.com
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

/*!
	\file HexIStream.hpp
	\brief
	\author
	Created			: Adam Smith
	Last modified	: Adam Smith
	\date
	Created			: 12th January 2016
	Last Modified	: 12th January 2016
*/

#include "Solaire/Core/IStream.hpp"
#include "Solaire/Core/Container.hpp"
#include "Solaire/Core/Maths.hpp"

namespace Solaire {

	class HexToBinIStream : public IStream {
    private:
        IStream& mStream;
    private:
        uint8_t readByte() throw() {
            HexChar buffer[2];
            mStream >> buffer[0];
            if(mStream.end()) {
                buffer[1] = '0';
            }else {
                mStream >> buffer[1];
            }
            return hexToBin8(buffer);
        }

        // Inherited from IStream

        uint8_t SOLAIRE_EXPORT_CALL readU8() throw() override {
            return readByte();
        }

        uint16_t SOLAIRE_EXPORT_CALL readU16() throw() override {
            return combine16(
                readByte(),
                readByte()
            );
        }

        uint32_t SOLAIRE_EXPORT_CALL readU32() throw() override {
            return combine32(
                readByte(),
                readByte(),
                readByte(),
                readByte()
            );
        }

        uint64_t SOLAIRE_EXPORT_CALL readU64() throw() override {
            return combine64(
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte()
            );
        }

        int8_t SOLAIRE_EXPORT_CALL readI8() throw() override {
            return signCast(readByte());
        }

        int16_t SOLAIRE_EXPORT_CALL readI16() throw() override {
            return signCast(combine16(
                readByte(),
                readByte()
            ));
        }

        int32_t SOLAIRE_EXPORT_CALL readI32() throw() override {
            return signCast(combine32(
                readByte(),
                readByte(),
                readByte(),
                readByte()
            ));

        }

        int64_t SOLAIRE_EXPORT_CALL readI64() throw() override {
            return signCast(combine64(
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte()
            ));
        }

        float SOLAIRE_EXPORT_CALL readF() throw() override {
            //! \todo Optimise readF
            float tmp;
            read(&tmp, sizeof(float));
            return tmp;
        }

        double SOLAIRE_EXPORT_CALL readD() throw() override {
            //! \todo Optimise readD
            double tmp;
            read(&tmp, sizeof(double));
            return tmp;
        }

        char SOLAIRE_EXPORT_CALL readC() throw() override {
            return static_cast<char>(readByte());
        }

    public:
        HexToBinIStream(IStream& aStream) :
            mStream(aStream)
        {}

        SOLAIRE_EXPORT_CALL ~HexToBinIStream() {

        }

        // Inherited from IStream

        void SOLAIRE_EXPORT_CALL read(void* const aAddress, const uint32_t aBytes) throw() override {
            uint8_t* const ptr = static_cast<uint8_t*>(aAddress);
            for(uint32_t i = 0; i < aBytes; ++i) ptr[i] = readByte();
        }

        bool SOLAIRE_EXPORT_CALL isOffsetable() const throw() override {
            return mStream.isOffsetable();
        }

        int32_t SOLAIRE_EXPORT_CALL getOffset() const throw() override {
            return mStream.getOffset();
        }

        bool SOLAIRE_EXPORT_CALL setOffset(const int32_t aOffset) throw() override {
            return mStream.setOffset(aOffset);
        }

        bool SOLAIRE_EXPORT_CALL end() const throw() override {
            return mStream.end();
        }

    };

    class BinToHexIStream : public IStream {
    private:
        IStream& mStream;
        HexChar mBuffer;
        bool mBufferSet;
    private:
        uint8_t readByte() throw() {
            if(mBufferSet) {
                mBufferSet = false;
                return mBuffer;
            }

            HexChar buf[2];
            uint8_t byte;
            mStream >> byte;
            bin8ToHex(byte, buf);
            mBufferSet = true;
            mBuffer = buf[1];
            return buf[0];
        }

        // Inherited from IStream

        uint8_t SOLAIRE_EXPORT_CALL readU8() throw() override {
            return readByte();
        }

        uint16_t SOLAIRE_EXPORT_CALL readU16() throw() override {
            return combine16(
                readByte(),
                readByte()
            );
        }

        uint32_t SOLAIRE_EXPORT_CALL readU32() throw() override {
            return combine32(
                readByte(),
                readByte(),
                readByte(),
                readByte()
            );
        }

        uint64_t SOLAIRE_EXPORT_CALL readU64() throw() override {
            return combine64(
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte()
            );
        }

        int8_t SOLAIRE_EXPORT_CALL readI8() throw() override {
            return signCast(readByte());
        }

        int16_t SOLAIRE_EXPORT_CALL readI16() throw() override {
            return signCast(combine16(
                readByte(),
                readByte()
            ));
        }

        int32_t SOLAIRE_EXPORT_CALL readI32() throw() override {
            return signCast(combine32(
                readByte(),
                readByte(),
                readByte(),
                readByte()
            ));
        }

        int64_t SOLAIRE_EXPORT_CALL readI64() throw() override {
            return signCast(combine64(
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte(),
                readByte()
            ));
        }

        float SOLAIRE_EXPORT_CALL readF() throw() override {
            float value;
            read(&value, sizeof(float));
            return value;
        }

        double SOLAIRE_EXPORT_CALL readD() throw() override {
            double value;
            read(&value, sizeof(double));
            return value;
        }

        char SOLAIRE_EXPORT_CALL readC() throw() override {
            return static_cast<char>(readByte());
        }

    public:
        BinToHexIStream(IStream& aStream) :
            mStream(aStream),
            mBufferSet(false)
        {}

        SOLAIRE_EXPORT_CALL ~BinToHexIStream() {
            //! \todo Handle trailing byte
        }

        // Inherited from IStream

        void SOLAIRE_EXPORT_CALL read(void* const aAddress, const uint32_t aBytes) throw() override {
            uint8_t* const ptr = static_cast<uint8_t*>(aAddress);
            for(uint32_t i = 0; i < aBytes; ++i) {
                ptr[i] = readByte();
            }
        }

        bool SOLAIRE_EXPORT_CALL isOffsetable() const throw() override {
            return mStream.isOffsetable();
        }

        int32_t SOLAIRE_EXPORT_CALL getOffset() const throw() override {
            return mStream.getOffset();
        }

        bool SOLAIRE_EXPORT_CALL setOffset(const int32_t aOffset) throw() override {
            return mStream.setOffset(aOffset);
        }

        bool SOLAIRE_EXPORT_CALL end() const throw() override {
            return mStream.end();
        }

    };

}

#endif
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2013 Juergen Riegel                                     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <QContextMenuEvent>
# include <QMenu>
#endif

#include <Base/Console.h>
#include <Base/Quantity.h>
#include <Base/Exception.h>
#include <App/Application.h>

#include "InputField.h"
#include "BitmapFactory.h"

using namespace Gui;
using namespace Base;

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

InputField::InputField ( QWidget * parent )
  : QLineEdit(parent),
  StepSize(1.0),
  Maximum(DOUBLE_MAX),
  Minimum(-DOUBLE_MAX),
  HistorySize(5),
  SaveSize(5)
{
    iconLabel = new QLabel(this);
    iconLabel->setCursor(Qt::ArrowCursor);
    QPixmap pixmap = BitmapFactory().pixmapFromSvg(":/icons/button_valid.svg", QSize(sizeHint().height(),sizeHint().height()));
    iconLabel->setPixmap(pixmap);
    iconLabel->setStyleSheet(QString::fromAscii("QLabel { border: none; padding: 0px; }"));
    iconLabel->hide();
    connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateIconLabel(const QString&)));
    int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
    setStyleSheet(QString::fromAscii("QLineEdit { padding-right: %1px } ").arg(iconLabel->sizeHint().width() + frameWidth + 1));
    QSize msz = minimumSizeHint();
    setMinimumSize(qMax(msz.width(), iconLabel->sizeHint().height() + frameWidth * 2 + 2),
                   qMax(msz.height(), iconLabel->sizeHint().height() + frameWidth * 2 + 2));

    this->setContextMenuPolicy(Qt::DefaultContextMenu);

    QObject::connect(this, SIGNAL(textChanged  (QString)),
                     this, SLOT(newInput(QString)));
}

InputField::~InputField()
{
}

void InputField::resizeEvent(QResizeEvent *)
{
    QSize sz = iconLabel->sizeHint();
    int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
    iconLabel->move(rect().right() - frameWidth - sz.width(),
                    (rect().bottom() + 1 - sz.height())/2);
}

void InputField::updateIconLabel(const QString& text)
{
    iconLabel->setVisible(!text.isEmpty());
}

void InputField::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu *editMenu = createStandardContextMenu();
    editMenu->setTitle(tr("Edit"));
    QMenu* menu = new QMenu(QString::fromAscii("InputFieldContextmenu"));

    menu->addMenu(editMenu);
    menu->addSeparator();

    // datastructure to remember actions for values
    std::vector<QString> values;
    std::vector<QAction *> actions;

    // add the history menu part...
    std::vector<QString> history = getHistory();

    for(std::vector<QString>::const_iterator it = history.begin();it!= history.end();++it){
        actions.push_back(menu->addAction(*it));
        values.push_back(*it);
    }

    // add the save value portion of the menu
    menu->addSeparator();
    QAction *SaveValueAction = menu->addAction(tr("Save value"));
    std::vector<QString> savedValues = getSavedValues();

    for(std::vector<QString>::const_iterator it = savedValues.begin();it!= savedValues.end();++it){
        actions.push_back(menu->addAction(*it));
        values.push_back(*it);
    }

    // call the menu and wait until its back
    QAction *saveAction = menu->exec(event->globalPos());

    // look what the user has choosen
    if(saveAction == SaveValueAction)
        pushToSavedValues();
    else{
        int i=0;
        for(std::vector<QAction *>::const_iterator it = actions.begin();it!=actions.end();++it,i++)
            if(*it == saveAction)
                this->setText(values[i]);
    }

    delete menu;
}

void InputField::newInput(const QString & text)
{
    Quantity res;
    try{
        res = Quantity::parse(text);
    }catch(Base::Exception &e){
        ErrorText = e.what();
        this->setToolTip(QString::fromAscii(ErrorText.c_str()));
        QPixmap pixmap = BitmapFactory().pixmapFromSvg(":/icons/button_invalid.svg", QSize(sizeHint().height(),sizeHint().height()));
        iconLabel->setPixmap(pixmap);
        parseError(QString::fromAscii(ErrorText.c_str()));
        return;
    }

    QPixmap pixmap = BitmapFactory().pixmapFromSvg(":/icons/button_valid.svg", QSize(sizeHint().height(),sizeHint().height()));
    iconLabel->setPixmap(pixmap);

    ErrorText = "";
    this->setToolTip(QString::fromAscii(ErrorText.c_str()));
    actQuantity = res;
    double dFactor;
    res.getUserString(dFactor,actUnitStr);
    // calculate the number shown
    actUnitValue = res.getValue()/dFactor;
    // signaling
    valueChanged(res);

}

void InputField::pushToHistory(const QString &valueq)
{
    QString val;
    if(valueq.isEmpty())
        val = this->text();
    else
        val = valueq;

    // check if already in:
    std::vector<QString> hist = InputField::getHistory();
    for(std::vector<QString>::const_iterator it = hist.begin();it!=hist.end();++it)
        if( *it == val)
            return;

    std::string value(val.toUtf8());
    if(_handle.isValid()){
        char hist1[21];
        char hist0[21];
        for(int i = HistorySize -1 ; i>=0 ;i--){
            snprintf(hist1,20,"Hist%i",i+1);
            snprintf(hist0,20,"Hist%i",i);
            std::string tHist = _handle->GetASCII(hist0,"");
            if(tHist != "")
                _handle->SetASCII(hist1,tHist.c_str());
        }
        _handle->SetASCII("Hist0",value.c_str());
    }
}

std::vector<QString> InputField::getHistory(void)
{
    std::vector<QString> res;

    if(_handle.isValid()){
        std::string tmp;
        char hist[21];
        for(int i = 0 ; i< HistorySize ;i++){
            snprintf(hist,20,"Hist%i",i);
            tmp = _handle->GetASCII(hist,"");
            if( tmp != "")
                res.push_back(QString::fromUtf8(tmp.c_str()));
            else
                break; // end of history reached
        }
    }
    return res;
}

void InputField::setToLastUsedValue(void)
{
     std::vector<QString> hist = getHistory();
     if(hist.size()>0)
         this->setValue(Base::Quantity::parse(hist[0]));
}

void InputField::pushToSavedValues(const QString &valueq)
{
    std::string value;
    if(valueq.isEmpty())
        value = this->text().toUtf8().constData();
    else
        value = valueq.toUtf8().constData();

    if(_handle.isValid()){
        char hist1[21];
        char hist0[21];
        for(int i = SaveSize -1 ; i>=0 ;i--){
            snprintf(hist1,20,"Save%i",i+1);
            snprintf(hist0,20,"Save%i",i);
            std::string tHist = _handle->GetASCII(hist0,"");
            if(tHist != "")
                _handle->SetASCII(hist1,tHist.c_str());
        }
        _handle->SetASCII("Save0",value.c_str());
    }
}

std::vector<QString> InputField::getSavedValues(void)
{
    std::vector<QString> res;

    if(_handle.isValid()){
        std::string tmp;
        char hist[21];
        for(int i = 0 ; i< SaveSize ;i++){
            snprintf(hist,20,"Save%i",i);
            tmp = _handle->GetASCII(hist,"");
            if( tmp != "")
                res.push_back(QString::fromUtf8(tmp.c_str()));
            else
                break; // end of history reached
        }
    }
    return res;
}

/** Sets the preference path to \a path. */
void InputField::setParamGrpPath( const QByteArray& path )
{

  _handle = App::GetApplication().GetParameterGroupByPath( path);
  if (_handle.isValid())
      sGroupString = (const char*)path;
}

/** Returns the widget's preferences path. */
QByteArray InputField::paramGrpPath() const
{
    if(_handle.isValid())
        return sGroupString.c_str();
    return QByteArray();
}

/// sets the field with a quantity
void InputField::setValue(const Base::Quantity& quant)
{
    actQuantity = quant;
    if(!quant.getUnit().isEmpty())
        actUnit = quant.getUnit();

    double dFactor;
    setText(quant.getUserString(dFactor,actUnitStr));
    actUnitValue = quant.getValue()/dFactor;
}

void InputField::setUnit(const Base::Unit& unit)
{
    actUnit = unit;
}

/// get the value of the singleStep property
double InputField::singleStep(void)const
{
    return StepSize;
}

/// set the value of the singleStep property
void InputField::setSingleStep(double s)
{
    StepSize = s;
}

/// get the value of the maximum property
double InputField::maximum(void)const
{
    return Maximum;
}

/// set the value of the maximum property
void InputField::setMaximum(double m)
{
    Maximum = m;
}

/// get the value of the minimum property
double InputField::minimum(void)const
{
    return Minimum;
}

/// set the value of the minimum property
void InputField::setMinimum(double m)
{
    Minimum = m;
}

void InputField::setUnitText(QString str)
{
    Base::Quantity quant = Base::Quantity::parse(str);
    setUnit(quant.getUnit());
}

QString InputField::getUnitText(void)
{
    return actUnitStr;
}

// get the value of the minimum property
int InputField::historySize(void)const
{
    return HistorySize;
}
// set the value of the minimum property
void InputField::setHistorySize(int i)
{
    assert(i>=0);
    assert(i<100);

    HistorySize = i;
}

void InputField::selectNumber(void)
{
    QByteArray str = text().toLatin1();
    unsigned int i = 0;

    while ( (str.at(i) >= '0' && str.at(i) <= '9') || str.at(i)== ',' ||  str.at(i)== '.'||  str.at(i)== '-' )
        i++;

    setSelection(0,i);

}

void InputField::wheelEvent ( QWheelEvent * event )
{
     int numDegrees = event->delta() / 8;
     int numSteps = numDegrees / 15;

     double val = actUnitValue + numSteps;

     this->setText( QString::fromUtf8("%L1 %2").arg(val).arg(actUnitStr));

     //if (event->orientation() == Qt::Horizontal) {
     //    scrollHorizontally(numSteps);
     //} else {
     //    scrollVertically(numSteps);
     //}
     event->accept();
}
// --------------------------------------------------------------------

#include "moc_InputField.cpp"
<commit_msg>+ emit valueChanged(double) signal from InputField<commit_after>/***************************************************************************
 *   Copyright (c) 2013 Juergen Riegel                                     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <QContextMenuEvent>
# include <QMenu>
#endif

#include <Base/Console.h>
#include <Base/Quantity.h>
#include <Base/Exception.h>
#include <App/Application.h>

#include "InputField.h"
#include "BitmapFactory.h"

using namespace Gui;
using namespace Base;

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

InputField::InputField ( QWidget * parent )
  : QLineEdit(parent),
  StepSize(1.0),
  Maximum(DOUBLE_MAX),
  Minimum(-DOUBLE_MAX),
  HistorySize(5),
  SaveSize(5)
{
    iconLabel = new QLabel(this);
    iconLabel->setCursor(Qt::ArrowCursor);
    QPixmap pixmap = BitmapFactory().pixmapFromSvg(":/icons/button_valid.svg", QSize(sizeHint().height(),sizeHint().height()));
    iconLabel->setPixmap(pixmap);
    iconLabel->setStyleSheet(QString::fromAscii("QLabel { border: none; padding: 0px; }"));
    iconLabel->hide();
    connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateIconLabel(const QString&)));
    int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
    setStyleSheet(QString::fromAscii("QLineEdit { padding-right: %1px } ").arg(iconLabel->sizeHint().width() + frameWidth + 1));
    QSize msz = minimumSizeHint();
    setMinimumSize(qMax(msz.width(), iconLabel->sizeHint().height() + frameWidth * 2 + 2),
                   qMax(msz.height(), iconLabel->sizeHint().height() + frameWidth * 2 + 2));

    this->setContextMenuPolicy(Qt::DefaultContextMenu);

    QObject::connect(this, SIGNAL(textChanged  (QString)),
                     this, SLOT(newInput(QString)));
}

InputField::~InputField()
{
}

void InputField::resizeEvent(QResizeEvent *)
{
    QSize sz = iconLabel->sizeHint();
    int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
    iconLabel->move(rect().right() - frameWidth - sz.width(),
                    (rect().bottom() + 1 - sz.height())/2);
}

void InputField::updateIconLabel(const QString& text)
{
    iconLabel->setVisible(!text.isEmpty());
}

void InputField::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu *editMenu = createStandardContextMenu();
    editMenu->setTitle(tr("Edit"));
    QMenu* menu = new QMenu(QString::fromAscii("InputFieldContextmenu"));

    menu->addMenu(editMenu);
    menu->addSeparator();

    // datastructure to remember actions for values
    std::vector<QString> values;
    std::vector<QAction *> actions;

    // add the history menu part...
    std::vector<QString> history = getHistory();

    for(std::vector<QString>::const_iterator it = history.begin();it!= history.end();++it){
        actions.push_back(menu->addAction(*it));
        values.push_back(*it);
    }

    // add the save value portion of the menu
    menu->addSeparator();
    QAction *SaveValueAction = menu->addAction(tr("Save value"));
    std::vector<QString> savedValues = getSavedValues();

    for(std::vector<QString>::const_iterator it = savedValues.begin();it!= savedValues.end();++it){
        actions.push_back(menu->addAction(*it));
        values.push_back(*it);
    }

    // call the menu and wait until its back
    QAction *saveAction = menu->exec(event->globalPos());

    // look what the user has choosen
    if(saveAction == SaveValueAction)
        pushToSavedValues();
    else{
        int i=0;
        for(std::vector<QAction *>::const_iterator it = actions.begin();it!=actions.end();++it,i++)
            if(*it == saveAction)
                this->setText(values[i]);
    }

    delete menu;
}

void InputField::newInput(const QString & text)
{
    Quantity res;
    try{
        res = Quantity::parse(text);
    }catch(Base::Exception &e){
        ErrorText = e.what();
        this->setToolTip(QString::fromAscii(ErrorText.c_str()));
        QPixmap pixmap = BitmapFactory().pixmapFromSvg(":/icons/button_invalid.svg", QSize(sizeHint().height(),sizeHint().height()));
        iconLabel->setPixmap(pixmap);
        parseError(QString::fromAscii(ErrorText.c_str()));
        return;
    }

    QPixmap pixmap = BitmapFactory().pixmapFromSvg(":/icons/button_valid.svg", QSize(sizeHint().height(),sizeHint().height()));
    iconLabel->setPixmap(pixmap);

    ErrorText = "";
    this->setToolTip(QString::fromAscii(ErrorText.c_str()));
    actQuantity = res;
    double dFactor;
    res.getUserString(dFactor,actUnitStr);
    // calculate the number shown
    actUnitValue = res.getValue()/dFactor;
    // signaling
    valueChanged(res);
    valueChanged(res.getValue());
}

void InputField::pushToHistory(const QString &valueq)
{
    QString val;
    if(valueq.isEmpty())
        val = this->text();
    else
        val = valueq;

    // check if already in:
    std::vector<QString> hist = InputField::getHistory();
    for(std::vector<QString>::const_iterator it = hist.begin();it!=hist.end();++it)
        if( *it == val)
            return;

    std::string value(val.toUtf8());
    if(_handle.isValid()){
        char hist1[21];
        char hist0[21];
        for(int i = HistorySize -1 ; i>=0 ;i--){
            snprintf(hist1,20,"Hist%i",i+1);
            snprintf(hist0,20,"Hist%i",i);
            std::string tHist = _handle->GetASCII(hist0,"");
            if(tHist != "")
                _handle->SetASCII(hist1,tHist.c_str());
        }
        _handle->SetASCII("Hist0",value.c_str());
    }
}

std::vector<QString> InputField::getHistory(void)
{
    std::vector<QString> res;

    if(_handle.isValid()){
        std::string tmp;
        char hist[21];
        for(int i = 0 ; i< HistorySize ;i++){
            snprintf(hist,20,"Hist%i",i);
            tmp = _handle->GetASCII(hist,"");
            if( tmp != "")
                res.push_back(QString::fromUtf8(tmp.c_str()));
            else
                break; // end of history reached
        }
    }
    return res;
}

void InputField::setToLastUsedValue(void)
{
     std::vector<QString> hist = getHistory();
     if(hist.size()>0)
         this->setValue(Base::Quantity::parse(hist[0]));
}

void InputField::pushToSavedValues(const QString &valueq)
{
    std::string value;
    if(valueq.isEmpty())
        value = this->text().toUtf8().constData();
    else
        value = valueq.toUtf8().constData();

    if(_handle.isValid()){
        char hist1[21];
        char hist0[21];
        for(int i = SaveSize -1 ; i>=0 ;i--){
            snprintf(hist1,20,"Save%i",i+1);
            snprintf(hist0,20,"Save%i",i);
            std::string tHist = _handle->GetASCII(hist0,"");
            if(tHist != "")
                _handle->SetASCII(hist1,tHist.c_str());
        }
        _handle->SetASCII("Save0",value.c_str());
    }
}

std::vector<QString> InputField::getSavedValues(void)
{
    std::vector<QString> res;

    if(_handle.isValid()){
        std::string tmp;
        char hist[21];
        for(int i = 0 ; i< SaveSize ;i++){
            snprintf(hist,20,"Save%i",i);
            tmp = _handle->GetASCII(hist,"");
            if( tmp != "")
                res.push_back(QString::fromUtf8(tmp.c_str()));
            else
                break; // end of history reached
        }
    }
    return res;
}

/** Sets the preference path to \a path. */
void InputField::setParamGrpPath( const QByteArray& path )
{

  _handle = App::GetApplication().GetParameterGroupByPath( path);
  if (_handle.isValid())
      sGroupString = (const char*)path;
}

/** Returns the widget's preferences path. */
QByteArray InputField::paramGrpPath() const
{
    if(_handle.isValid())
        return sGroupString.c_str();
    return QByteArray();
}

/// sets the field with a quantity
void InputField::setValue(const Base::Quantity& quant)
{
    actQuantity = quant;
    if(!quant.getUnit().isEmpty())
        actUnit = quant.getUnit();

    double dFactor;
    setText(quant.getUserString(dFactor,actUnitStr));
    actUnitValue = quant.getValue()/dFactor;
}

void InputField::setUnit(const Base::Unit& unit)
{
    actUnit = unit;
}

/// get the value of the singleStep property
double InputField::singleStep(void)const
{
    return StepSize;
}

/// set the value of the singleStep property
void InputField::setSingleStep(double s)
{
    StepSize = s;
}

/// get the value of the maximum property
double InputField::maximum(void)const
{
    return Maximum;
}

/// set the value of the maximum property
void InputField::setMaximum(double m)
{
    Maximum = m;
}

/// get the value of the minimum property
double InputField::minimum(void)const
{
    return Minimum;
}

/// set the value of the minimum property
void InputField::setMinimum(double m)
{
    Minimum = m;
}

void InputField::setUnitText(QString str)
{
    Base::Quantity quant = Base::Quantity::parse(str);
    setUnit(quant.getUnit());
}

QString InputField::getUnitText(void)
{
    return actUnitStr;
}

// get the value of the minimum property
int InputField::historySize(void)const
{
    return HistorySize;
}
// set the value of the minimum property
void InputField::setHistorySize(int i)
{
    assert(i>=0);
    assert(i<100);

    HistorySize = i;
}

void InputField::selectNumber(void)
{
    QByteArray str = text().toLatin1();
    unsigned int i = 0;

    while ( (str.at(i) >= '0' && str.at(i) <= '9') || str.at(i)== ',' ||  str.at(i)== '.'||  str.at(i)== '-' )
        i++;

    setSelection(0,i);

}

void InputField::wheelEvent ( QWheelEvent * event )
{
     int numDegrees = event->delta() / 8;
     int numSteps = numDegrees / 15;

     double val = actUnitValue + numSteps;

     this->setText( QString::fromUtf8("%L1 %2").arg(val).arg(actUnitStr));

     //if (event->orientation() == Qt::Horizontal) {
     //    scrollHorizontally(numSteps);
     //} else {
     //    scrollVertically(numSteps);
     //}
     event->accept();
}
// --------------------------------------------------------------------

#include "moc_InputField.cpp"
<|endoftext|>


<commit_before>#include <ostream>
#include <string>

#include <ppl.h>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include <common/CapricaConfig.h>

#include <papyrus/PapyrusResolutionContext.h>
#include <papyrus/PapyrusScript.h>
#include <papyrus/parser/PapyrusParser.h>

#include <pex/PexAsmWriter.h>
#include <pex/PexReader.h>
#include <pex/PexWriter.h>
#include <pex/parser/PexAsmParser.h>

void compileScript(std::string filename) {
  std::cout << "Compiling " << filename << std::endl;
  auto path = boost::filesystem::path(filename);
  auto baseName = boost::filesystem::basename(path.filename());
  auto ext = boost::filesystem::extension(filename);
  if (!_stricmp(ext.c_str(), ".psc")) {
    auto parser = new caprica::papyrus::parser::PapyrusParser(filename);
    auto a = parser->parseScript();
    caprica::CapricaError::exitIfErrors();
    delete parser;
    auto ctx = new caprica::papyrus::PapyrusResolutionContext();
    a->semantic(ctx);
    caprica::CapricaError::exitIfErrors();
    auto pex = a->buildPex();
    caprica::CapricaError::exitIfErrors();
    delete ctx;
    delete a;
    std::ofstream strm(caprica::CapricaConfig::outputDirectory + baseName + ".pex", std::ofstream::binary);
    caprica::pex::PexWriter wtr(strm);
    pex->write(wtr);

    if (caprica::CapricaConfig::dumpPexAsm) {
      std::ofstream asmStrm(caprica::CapricaConfig::outputDirectory + baseName + ".pas", std::ofstream::binary);
      caprica::pex::PexAsmWriter asmWtr(asmStrm);
      pex->writeAsm(asmWtr);
    }

    delete pex;
  } else if (!_stricmp(ext.c_str(), ".pas")) {
    auto parser = new caprica::pex::parser::PexAsmParser(filename);
    auto pex = parser->parseFile();
    caprica::CapricaError::exitIfErrors();
    delete parser;
    std::ofstream strm(caprica::CapricaConfig::outputDirectory + baseName + ".pex", std::ofstream::binary);
    caprica::pex::PexWriter wtr(strm);
    pex->write(wtr);
    delete pex;
  } else if (!_stricmp(ext.c_str(), ".pex")) {
    caprica::pex::PexReader rdr(filename);
    auto pex = caprica::pex::PexFile::read(rdr);
    caprica::CapricaError::exitIfErrors();
    std::ofstream asmStrm(caprica::CapricaConfig::outputDirectory + baseName + ".pas", std::ofstream::binary);
    caprica::pex::PexAsmWriter asmWtr(asmStrm);
    pex->writeAsm(asmWtr);
    delete pex;
  } else {
    std::cout << "Don't know how to compile " << filename << "!" << std::endl;
  }
}

std::pair<std::string, std::string> parseOddArguments(const std::string& str) {
  if (str == "WE")
    return std::make_pair("all-warnings-as-errors", "");
  else if (str.find("we") == 0)
    return std::make_pair("warning-as-error", str.substr(2));
  else if (str.find("wd") == 0)
    return std::make_pair("disable-warning", str.substr(2));
  else
    return std::make_pair(std::string(), std::string());
}

bool parseArgs(int argc, char* argv[], std::vector<std::string>& filesToCompile) {
  namespace po = boost::program_options;
  namespace conf = caprica::CapricaConfig;

  try {
    po::options_description desc("General");
    desc.add_options()
      ("help,h", "Print usage information.")
      ("import,i", po::value<std::vector<std::string>>(&conf::importDirectories), "Set the compiler's import directories.")
      ("optimize,O", po::bool_switch(&conf::enableOptimizations)->default_value(false), "Enable optimizations.")
      ("output,o", po::value<std::string>(&conf::outputDirectory)->default_value(boost::filesystem::absolute("./").string()), "Set the directory to save compiler output to.")
      ("parallel-compile,p", po::bool_switch(&conf::compileInParallel)->default_value(false), "Compile files in parallel.")
      ("dump-asm", po::bool_switch(&conf::dumpPexAsm)->default_value(false), "Dump the PEX assembly code for the input files.")
      ("all-warnings-as-errors", po::bool_switch(&conf::treatWarningsAsErrors)->default_value(false), "Treat all warnings as if they were errors.")
      ("warning-as-error", po::value<std::vector<size_t>>(), "Treat a specific warning as an error.")
      ("disable-warning", po::value<std::vector<size_t>>(), "Disable a specific warning.")
    ;

    po::options_description champollionCompatDesc("Champollion Compatibility");
    champollionCompatDesc.add_options()
      ("champollion-compat", po::value<bool>()->default_value(true)->implicit_value(true), "Enable a few options that make it easier to compile Papyrus code decompiled by Champollion.")
      ("allow-compiler-identifiers", po::bool_switch(&conf::allowCompilerIdentifiers)->default_value(false), "Allow identifiers to be prefixed with ::, which is normally reserved for compiler identifiers.")
      ("allow-decompiled-struct-references", po::bool_switch(&conf::allowDecompiledStructNameRefs)->default_value(false), "Allow the name of structs to be prefixed with the containing object name, followed by a #, then the name of the struct.")
    ;

    po::options_description advancedDesc("Advanced");
    advancedDesc.add_options()
      ("enable-ck-optimizations", po::value<bool>(&conf::enableCKOptimizations)->default_value(true), "Enable optimizations that the CK compiler normally does regardless of the -optimize switch.")
      ("enable-debug-info", po::value<bool>(&conf::emitDebugInfo)->default_value(true), "Enable the generation of debug info. Disabling this will result in Property Groups not showing up in the Creation Kit for the compiled script. This also removes the line number and struct order information.")
      ("enable-language-extensions", po::value<bool>(&conf::enableLanguageExtensions)->default_value(true), "Enable Caprica's extensions to the Papyrus language.")
      ("enable-speculative-syntax", po::value<bool>(&conf::enableSpeculativeSyntax)->default_value(true), "Enable the speculated syntax for the new Papyrus features in Fallout 4.")
    ;

    po::options_description hiddenDesc("");
    hiddenDesc.add_options()
      ("input-file", po::value<std::vector<std::string>>(), "The input file.")
    ;

    po::positional_options_description p;
    p.add("input-file", -1);

    po::options_description visibleDesc("Caprica Papyrus Compiler v0.0.9\nUsage: Caprica <sourceFile/directory>\nNote that when passing a directory, only Papyrus script files (*.psc) in it will be compiled. Pex (*.pex) and Pex assembly (*.pas) files will be ignored.");
    visibleDesc.add(desc).add(champollionCompatDesc).add(advancedDesc);

    po::options_description commandLineDesc("");
    commandLineDesc.add(visibleDesc).add(hiddenDesc);

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv)
              .options(commandLineDesc)
              .extra_parser(parseOddArguments)
              .positional(p)
              .run(), vm);
    po::notify(vm);

    if (vm.count("help") || !vm.count("input-file")) {
      std::cout << visibleDesc << std::endl;
      return false;
    }

    if (vm["champollion-compat"].as<bool>()) {
      conf::allowCompilerIdentifiers = true;
      conf::allowDecompiledStructNameRefs = true;
    }

    if (vm.count("warning-as-error")) {
      auto warnsAsErrs = vm["warning-as-error"].as<std::vector<size_t>>();
      conf::warningsToHandleAsErrors.reserve(warnsAsErrs.size());
      for (auto f : warnsAsErrs) {
        if (conf::warningsToHandleAsErrors.count(f)) {
          std::cout << "Warning " << f << " was already marked as an error." << std::endl;
          return false;
        }
        conf::warningsToHandleAsErrors.insert(f);
      }
    }

    if (vm.count("disable-warning")) {
      auto warnsIgnored = vm["disable-warning"].as<std::vector<size_t>>();
      conf::warningsToIgnore.reserve(warnsIgnored.size());
      for (auto f : warnsIgnored) {
        if (conf::warningsToIgnore.count(f)) {
          std::cout << "Warning " << f << " was already disabled." << std::endl;
          return false;
        }
        conf::warningsToIgnore.insert(f);
      }
    }

    auto filesPassed = vm["input-file"].as<std::vector<std::string>>();
    filesToCompile.reserve(filesPassed.size());
    for (auto f : filesPassed) {
      if (!boost::filesystem::exists(f)) {
        std::cout << "Unable to locate input file '" << f << "'." << std::endl;
        return false;
      }
      if (boost::filesystem::is_directory(f)) {
        boost::system::error_code ec;
        for (auto e : boost::filesystem::directory_iterator(f, ec)) {
          if (e.path().extension().string() == ".psc")
            filesToCompile.push_back(e.path().string());
        }
      } else {
        auto ext = boost::filesystem::extension(f);
        if (_stricmp(ext.c_str(), ".psc") && _stricmp(ext.c_str(), ".pas") && _stricmp(ext.c_str(), ".pex")) {
          std::cout << "Don't know how to handle input file '" << f << "'!" << std::endl;
          std::cout << "Expected either a Papyrus file (*.psc), Pex assembly file (*.pas), or a Pex file (*.pex)!" << std::endl;
          return false;
        }
        filesToCompile.push_back(f);
      }
    }
  } catch (const std::exception& ex) {
    std::cout << ex.what() << std::endl;
    return false;
  }

  return true;
}

int main(int argc, char* argv[])
{
  std::vector<std::string> filesToCompile;
  if (!parseArgs(argc, argv, filesToCompile)) {
    __debugbreak();
    return -1;
  }

  try {
    if (caprica::CapricaConfig::compileInParallel) {
      concurrency::parallel_for_each(filesToCompile.begin(), filesToCompile.end(), [](std::string fl) {
        compileScript(fl);
      });
    } else {
      for (auto& file : filesToCompile)
        compileScript(file);
    }
  } catch (const std::runtime_error& err) {
    err;
    //std::cout << err.what() << std::endl;
    __debugbreak();
  }

  return 0;
}

<commit_msg>Don't crash when an error happens. It helps if you don't call __debugbreak when there is no debugger attached. Also made a minor adjustment to how the base usage text is displayed.<commit_after>#include <ostream>
#include <string>

#include <ppl.h>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include <common/CapricaConfig.h>

#include <papyrus/PapyrusResolutionContext.h>
#include <papyrus/PapyrusScript.h>
#include <papyrus/parser/PapyrusParser.h>

#include <pex/PexAsmWriter.h>
#include <pex/PexReader.h>
#include <pex/PexWriter.h>
#include <pex/parser/PexAsmParser.h>

#include <Windows.h>

static void compileScript(std::string filename) {
  std::cout << "Compiling " << filename << std::endl;
  auto path = boost::filesystem::path(filename);
  auto baseName = boost::filesystem::basename(path.filename());
  auto ext = boost::filesystem::extension(filename);
  if (!_stricmp(ext.c_str(), ".psc")) {
    auto parser = new caprica::papyrus::parser::PapyrusParser(filename);
    auto a = parser->parseScript();
    caprica::CapricaError::exitIfErrors();
    delete parser;
    auto ctx = new caprica::papyrus::PapyrusResolutionContext();
    a->semantic(ctx);
    caprica::CapricaError::exitIfErrors();
    auto pex = a->buildPex();
    caprica::CapricaError::exitIfErrors();
    delete ctx;
    delete a;
    std::ofstream strm(caprica::CapricaConfig::outputDirectory + baseName + ".pex", std::ofstream::binary);
    caprica::pex::PexWriter wtr(strm);
    pex->write(wtr);

    if (caprica::CapricaConfig::dumpPexAsm) {
      std::ofstream asmStrm(caprica::CapricaConfig::outputDirectory + baseName + ".pas", std::ofstream::binary);
      caprica::pex::PexAsmWriter asmWtr(asmStrm);
      pex->writeAsm(asmWtr);
    }

    delete pex;
  } else if (!_stricmp(ext.c_str(), ".pas")) {
    auto parser = new caprica::pex::parser::PexAsmParser(filename);
    auto pex = parser->parseFile();
    caprica::CapricaError::exitIfErrors();
    delete parser;
    std::ofstream strm(caprica::CapricaConfig::outputDirectory + baseName + ".pex", std::ofstream::binary);
    caprica::pex::PexWriter wtr(strm);
    pex->write(wtr);
    delete pex;
  } else if (!_stricmp(ext.c_str(), ".pex")) {
    caprica::pex::PexReader rdr(filename);
    auto pex = caprica::pex::PexFile::read(rdr);
    caprica::CapricaError::exitIfErrors();
    std::ofstream asmStrm(caprica::CapricaConfig::outputDirectory + baseName + ".pas", std::ofstream::binary);
    caprica::pex::PexAsmWriter asmWtr(asmStrm);
    pex->writeAsm(asmWtr);
    delete pex;
  } else {
    std::cout << "Don't know how to compile " << filename << "!" << std::endl;
  }
}

static std::pair<std::string, std::string> parseOddArguments(const std::string& str) {
  if (str == "WE")
    return std::make_pair("all-warnings-as-errors", "");
  else if (str.find("we") == 0)
    return std::make_pair("warning-as-error", str.substr(2));
  else if (str.find("wd") == 0)
    return std::make_pair("disable-warning", str.substr(2));
  else
    return std::make_pair(std::string(), std::string());
}

static bool parseArgs(int argc, char* argv[], std::vector<std::string>& filesToCompile) {
  namespace po = boost::program_options;
  namespace conf = caprica::CapricaConfig;

  try {
    po::options_description desc("General");
    desc.add_options()
      ("help,h", "Print usage information.")
      ("import,i", po::value<std::vector<std::string>>(&conf::importDirectories), "Set the compiler's import directories.")
      ("optimize,O", po::bool_switch(&conf::enableOptimizations)->default_value(false), "Enable optimizations.")
      ("output,o", po::value<std::string>(&conf::outputDirectory)->default_value(boost::filesystem::current_path().string()), "Set the directory to save compiler output to.")
      ("parallel-compile,p", po::bool_switch(&conf::compileInParallel)->default_value(false), "Compile files in parallel.")
      ("dump-asm", po::bool_switch(&conf::dumpPexAsm)->default_value(false), "Dump the PEX assembly code for the input files.")
      ("all-warnings-as-errors", po::bool_switch(&conf::treatWarningsAsErrors)->default_value(false), "Treat all warnings as if they were errors.")
      ("warning-as-error", po::value<std::vector<size_t>>(), "Treat a specific warning as an error.")
      ("disable-warning", po::value<std::vector<size_t>>(), "Disable a specific warning.")
    ;

    po::options_description champollionCompatDesc("Champollion Compatibility");
    champollionCompatDesc.add_options()
      ("champollion-compat", po::value<bool>()->default_value(true)->implicit_value(true), "Enable a few options that make it easier to compile Papyrus code decompiled by Champollion.")
      ("allow-compiler-identifiers", po::bool_switch(&conf::allowCompilerIdentifiers)->default_value(false), "Allow identifiers to be prefixed with ::, which is normally reserved for compiler identifiers.")
      ("allow-decompiled-struct-references", po::bool_switch(&conf::allowDecompiledStructNameRefs)->default_value(false), "Allow the name of structs to be prefixed with the containing object name, followed by a #, then the name of the struct.")
    ;

    po::options_description advancedDesc("Advanced");
    advancedDesc.add_options()
      ("enable-ck-optimizations", po::value<bool>(&conf::enableCKOptimizations)->default_value(true), "Enable optimizations that the CK compiler normally does regardless of the -optimize switch.")
      ("enable-debug-info", po::value<bool>(&conf::emitDebugInfo)->default_value(true), "Enable the generation of debug info. Disabling this will result in Property Groups not showing up in the Creation Kit for the compiled script. This also removes the line number and struct order information.")
      ("enable-language-extensions", po::value<bool>(&conf::enableLanguageExtensions)->default_value(true), "Enable Caprica's extensions to the Papyrus language.")
      ("enable-speculative-syntax", po::value<bool>(&conf::enableSpeculativeSyntax)->default_value(true), "Enable the speculated syntax for the new Papyrus features in Fallout 4.")
    ;

    po::options_description hiddenDesc("");
    hiddenDesc.add_options()
      ("input-file", po::value<std::vector<std::string>>(), "The input file.")
    ;

    po::positional_options_description p;
    p.add("input-file", -1);

    po::options_description visibleDesc("");
    visibleDesc.add(desc).add(champollionCompatDesc).add(advancedDesc);

    po::options_description commandLineDesc("");
    commandLineDesc.add(visibleDesc).add(hiddenDesc);

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv)
              .options(commandLineDesc)
              .extra_parser(parseOddArguments)
              .positional(p)
              .run(), vm);
    po::notify(vm);

    if (vm.count("help") || !vm.count("input-file")) {
      std::cout << "Caprica Papyrus Compiler v0.0.9" << std::endl;
      std::cout << "Usage: Caprica <sourceFile / directory>" << std::endl;
      std::cout << "Note that when passing a directory, only Papyrus script files (*.psc) in it will be compiled. Pex (*.pex) and Pex assembly (*.pas) files will be ignored." << std::endl;
      std::cout << visibleDesc << std::endl;
      return false;
    }

    if (vm["champollion-compat"].as<bool>()) {
      conf::allowCompilerIdentifiers = true;
      conf::allowDecompiledStructNameRefs = true;
    }

    if (vm.count("warning-as-error")) {
      auto warnsAsErrs = vm["warning-as-error"].as<std::vector<size_t>>();
      conf::warningsToHandleAsErrors.reserve(warnsAsErrs.size());
      for (auto f : warnsAsErrs) {
        if (conf::warningsToHandleAsErrors.count(f)) {
          std::cout << "Warning " << f << " was already marked as an error." << std::endl;
          return false;
        }
        conf::warningsToHandleAsErrors.insert(f);
      }
    }

    if (vm.count("disable-warning")) {
      auto warnsIgnored = vm["disable-warning"].as<std::vector<size_t>>();
      conf::warningsToIgnore.reserve(warnsIgnored.size());
      for (auto f : warnsIgnored) {
        if (conf::warningsToIgnore.count(f)) {
          std::cout << "Warning " << f << " was already disabled." << std::endl;
          return false;
        }
        conf::warningsToIgnore.insert(f);
      }
    }

    auto filesPassed = vm["input-file"].as<std::vector<std::string>>();
    filesToCompile.reserve(filesPassed.size());
    for (auto f : filesPassed) {
      if (!boost::filesystem::exists(f)) {
        std::cout << "Unable to locate input file '" << f << "'." << std::endl;
        return false;
      }
      if (boost::filesystem::is_directory(f)) {
        boost::system::error_code ec;
        for (auto e : boost::filesystem::directory_iterator(f, ec)) {
          if (e.path().extension().string() == ".psc")
            filesToCompile.push_back(e.path().string());
        }
      } else {
        auto ext = boost::filesystem::extension(f);
        if (_stricmp(ext.c_str(), ".psc") && _stricmp(ext.c_str(), ".pas") && _stricmp(ext.c_str(), ".pex")) {
          std::cout << "Don't know how to handle input file '" << f << "'!" << std::endl;
          std::cout << "Expected either a Papyrus file (*.psc), Pex assembly file (*.pas), or a Pex file (*.pex)!" << std::endl;
          return false;
        }
        filesToCompile.push_back(f);
      }
    }
  } catch (const std::exception& ex) {
    std::cout << ex.what() << std::endl;
    return false;
  }

  return true;
}

static void breakIfDebugging() {
  if (IsDebuggerPresent()) {
    __debugbreak();
  }
}

int main(int argc, char* argv[])
{
  std::vector<std::string> filesToCompile;
  if (!parseArgs(argc, argv, filesToCompile)) {
    breakIfDebugging();
    return -1;
  }

  try {
    if (caprica::CapricaConfig::compileInParallel) {
      concurrency::parallel_for_each(filesToCompile.begin(), filesToCompile.end(), [](std::string fl) {
        compileScript(fl);
      });
    } else {
      for (auto& file : filesToCompile)
        compileScript(file);
    }
  } catch (const std::runtime_error&) {
    breakIfDebugging();
    return -1;
  }

  return 0;
}

<|endoftext|>


<commit_before>{
   //
   // To see the output of this macro, click begin_html here end_html
   //
   gROOT->Reset();
   c1 = new TCanvas("c1","Histogram Drawing Options",200,10,700,900);

   pad1 = new TPad("pad1","The pad with the function",0.03,0.62,0.50,0.92,21);
   pad2 = new TPad("pad2","The pad with the histogram",0.51,0.62,0.98,0.92,21);
   pad3 = new TPad("pad3","The pad with the histogram",0.03,0.02,0.97,0.57,21);
   pad1->Draw();
   pad2->Draw();
   pad3->Draw();
   //
   // We connect the ROOT file generated in a previous tutorial
   // see begin_html An example creating/filling/saving histograms/ntuples on file end_html
   //
   TFile example("hsimple.root");
   example.ls();

   // Draw a global picture title
   title = new TPaveLabel(0.1,0.94,0.9,0.98,
                    "Drawing options for one dimensional histograms");
   title->SetFillColor(16);
   title->SetTextFont(52);
   title->Draw();
   //
   // Draw histogram hpx in first pad with the default option.
   pad1->cd();
   pad1->GetFrame()->SetFillColor(18);
   hpx->SetFillColor(45);
   hpx->DrawCopy();
   label1 = new TPaveLabel(-3.5,700,-1,800,"Default option");
   label1->SetFillColor(42);
   label1->Draw();
   //
   // Draw hpx as a lego. Clicking on the lego area will show
   // a "transparent cube" to guide you rotating the lego in real time.
   pad2->cd();
   hpx->DrawCopy("lego1");
   label2 = new TPaveLabel(0.4,0.8,0.9,0.95,"option Lego1");
   label2->SetFillColor(42);
   label2->Draw();
   label2a = new TPaveLabel(-0.93,-1.08,0.25,-0.92,"Click on lego to rotate");
   label2a->SetFillColor(42);
   label2a->Draw();
   //
   // Draw hpx with its errors and a marker.
   pad3->cd();
   pad3->SetGridx();
   pad3->SetGridy();
   pad3->GetFrame()->SetFillColor(18);
   hpx->SetMarkerStyle(21);
   hpx->Draw("e1p");
   label3 = new TPaveLabel(2,600,3.5,650,"option e1p");
   label3->SetFillColor(42);
   label3->Draw();
   //
   // The following illustrates how to add comments using a PaveText.
   // Attributes of text/lines/boxes added to a PaveText can be modified.
   // The AddText function returns a pointer to the added object.
   pave = new TPaveText(-3.78,500,-1.2,750);
   pave->SetFillColor(42);
   TText *t1=pave->AddText("You can move");
   t1->SetTextColor(4);
   t1->SetTextSize(0.05);
   pave->AddText("Title and Stats pads");
   pave->AddText("X and Y axis");
   pave->AddText("You can modify bin contents");
   pave->Draw();
   c1->Update();
}
<commit_msg>Modify position of TPaveLabel in second pad (hidding stats box)<commit_after>{
   //
   // To see the output of this macro, click begin_html here end_html
   //
   gROOT->Reset();
   c1 = new TCanvas("c1","Histogram Drawing Options",200,10,700,900);

   pad1 = new TPad("pad1","The pad with the function",0.03,0.62,0.50,0.92,21);
   pad2 = new TPad("pad2","The pad with the histogram",0.51,0.62,0.98,0.92,21);
   pad3 = new TPad("pad3","The pad with the histogram",0.03,0.02,0.97,0.57,21);
   pad1->Draw();
   pad2->Draw();
   pad3->Draw();
   //
   // We connect the ROOT file generated in a previous tutorial
   // see begin_html An example creating/filling/saving histograms/ntuples on file end_html
   //
   TFile example("hsimple.root");
   example.ls();

   // Draw a global picture title
   title = new TPaveLabel(0.1,0.94,0.9,0.98,
                    "Drawing options for one dimensional histograms");
   title->SetFillColor(16);
   title->SetTextFont(52);
   title->Draw();
   //
   // Draw histogram hpx in first pad with the default option.
   pad1->cd();
   pad1->GetFrame()->SetFillColor(18);
   hpx->SetFillColor(45);
   hpx->DrawCopy();
   label1 = new TPaveLabel(-3.5,700,-1,800,"Default option");
   label1->SetFillColor(42);
   label1->Draw();
   //
   // Draw hpx as a lego. Clicking on the lego area will show
   // a "transparent cube" to guide you rotating the lego in real time.
   pad2->cd();
   hpx->DrawCopy("lego1");
   label2 = new TPaveLabel(-0.72,0.74,-0.22,0.88,"option Lego1");
   label2->SetFillColor(42);
   label2->Draw();
   label2a = new TPaveLabel(-0.93,-1.08,0.25,-0.92,"Click on lego to rotate");
   label2a->SetFillColor(42);
   label2a->Draw();
   //
   // Draw hpx with its errors and a marker.
   pad3->cd();
   pad3->SetGridx();
   pad3->SetGridy();
   pad3->GetFrame()->SetFillColor(18);
   hpx->SetMarkerStyle(21);
   hpx->Draw("e1p");
   label3 = new TPaveLabel(2,600,3.5,650,"option e1p");
   label3->SetFillColor(42);
   label3->Draw();
   //
   // The following illustrates how to add comments using a PaveText.
   // Attributes of text/lines/boxes added to a PaveText can be modified.
   // The AddText function returns a pointer to the added object.
   pave = new TPaveText(-3.78,500,-1.2,750);
   pave->SetFillColor(42);
   TText *t1=pave->AddText("You can move");
   t1->SetTextColor(4);
   t1->SetTextSize(0.05);
   pave->AddText("Title and Stats pads");
   pave->AddText("X and Y axis");
   pave->AddText("You can modify bin contents");
   pave->Draw();
   c1->Update();
}
<|endoftext|>