<commit_before>/**************************************************************************
 * Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved.      *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * 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 "AliTPCPreprocessor.h"
#include "AliShuttleInterface.h"

#include "AliCDBMetaData.h"
#include "AliDCSValue.h"
#include "AliLog.h"
#include "AliTPCSensorTempArray.h"
#include "AliTPCDBPressure.h"
#include "AliTPCROC.h"
#include "AliTPCCalROC.h"
#include "AliTPCCalPad.h"
#include "AliTPCCalibPedestal.h"

#include <TTimeStamp.h>

const Int_t kValCutTemp = 100;               // discard temperatures > 100 degrees
const Int_t kDiffCutTemp = 5;	             // discard temperature differences > 5 degrees
const TString kPedestalRunType = "PEDESTAL_RUN";  // pedestal run identifier

//
// This class is the SHUTTLE preprocessor for the TPC detector.
// It contains several components, this far the part containing
// temperatures is implemented
//

ClassImp(AliTPCPreprocessor)

//______________________________________________________________________________________________
AliTPCPreprocessor::AliTPCPreprocessor(AliShuttleInterface* shuttle) :
  AliPreprocessor("TPC",shuttle),
  fTemp(0), fPressure(0), fConfigOK(kTRUE), fROC(0)
{
  // constructor
  fROC = AliTPCROC::Instance();
}
//______________________________________________________________________________________________
// AliTPCPreprocessor::AliTPCPreprocessor(const AliTPCPreprocessor& org) :
//   AliPreprocessor(org),
//   fTemp(0), fPressure(0), fConfigOK(kTRUE)
// {
//   // copy constructor not implemented
//   //   -- missing underlying copy constructor in AliPreprocessor
//
//   Fatal("AliTPCPreprocessor", "copy constructor not implemented");
//
// //  fTemp = new AliTPCSensorTempArray(*(org.fTemp));
// }

//______________________________________________________________________________________________
AliTPCPreprocessor::~AliTPCPreprocessor()
{
  // destructor

  delete fTemp;
  delete fPressure;
}
//______________________________________________________________________________________________
AliTPCPreprocessor& AliTPCPreprocessor::operator = (const AliTPCPreprocessor& )
{
  Fatal("operator =", "assignment operator not implemented");
  return *this;
}

//______________________________________________________________________________________________
void AliTPCPreprocessor::Initialize(Int_t run, UInt_t startTime,
	UInt_t endTime)
{
  // Creates AliTestDataDCS object

  AliPreprocessor::Initialize(run, startTime, endTime);

	AliInfo(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run,
		TTimeStamp(startTime).AsString(),
		TTimeStamp(endTime).AsString()));

  // Temperature sensors

        TTree *confTree = 0;
	AliCDBEntry* entry = GetFromOCDB("Config", "Temperature");
        if (entry) confTree = (TTree*) entry->GetObject();
        if ( confTree==0 ) {
           AliError(Form("Temperature Config OCDB entry missing.\n"));
           Log("AliTPCPreprocsessor: Temperature Config OCDB entry missing.\n");
	   fConfigOK = kFALSE;
	   return;
        }
        fTemp = new AliTPCSensorTempArray(fStartTime, fEndTime, confTree);
	fTemp->SetValCut(kValCutTemp);
	fTemp->SetDiffCut(kDiffCutTemp);

  // Pressure sensors

        confTree=0;
	entry=0;
	entry = GetFromOCDB("Config", "Pressure");
        if (entry) confTree = (TTree*) entry->GetObject();
        if ( confTree==0 ) {
           AliError(Form("Pressure Config OCDB entry missing.\n"));
           Log("AliTPCPreprocsessor: Pressure Config OCDB entry missing.\n");
	   fConfigOK = kFALSE;
	   return;
        }
	fPressure = new AliDCSSensorArray(fStartTime, fEndTime, confTree);

}

//______________________________________________________________________________________________
UInt_t AliTPCPreprocessor::Process(TMap* dcsAliasMap)
{
  // Fills data into TPC calibrations objects

  // Amanda servers provide information directly through dcsAliasMap

  if (!dcsAliasMap) return 9;
  if (!fConfigOK) return 9;

  TString runType = GetRunType();

  // Temperature sensors are processed by AliTPCCalTemp

  UInt_t tempResult = MapTemperature(dcsAliasMap);
  UInt_t result=tempResult;

  // Pressure sensors

  UInt_t pressureResult = MapPressure(dcsAliasMap);
  result += pressureResult;

  // Other calibration information will be retrieved through FXS files
  //  examples:
  //    TList* fileSourcesDAQ = GetFile(AliShuttleInterface::kDAQ, "pedestals");
  //    const char* fileNamePed = GetFile(AliShuttleInterface::kDAQ, "pedestals", "LDC1");
  //
  //    TList* fileSourcesHLT = GetFile(AliShuttleInterface::kHLT, "calib");
  //    const char* fileNameHLT = GetFile(AliShuttleInterface::kHLT, "calib", "LDC1");

  if(runType == kPedestalRunType) {
    UInt_t pedestalResult = ExtractPedestals();
    result += pedestalResult;
  }

  return result;
}
//______________________________________________________________________________________________
UInt_t AliTPCPreprocessor::MapTemperature(TMap* dcsAliasMap)
{

   // extract DCS temperature maps. Perform fits to save space

  UInt_t result=0;
  TMap *map = fTemp->ExtractDCS(dcsAliasMap);
  if (map) {
    fTemp->MakeSplineFit(map);
    AliInfo(Form("Temperature values extracted, fits performed.\n"));
  } else {
    AliError(Form("No temperature map extracted.\n"));
    Log("AliTPCPreprocsessor: no temperature map extracted. \n");
    result=9;
  }
  delete map;
  // Now store the final CDB file

  if ( result == 0 ) {
        AliCDBMetaData metaData;
	metaData.SetBeamPeriod(0);
	metaData.SetResponsible("Haavard Helstrup");
	metaData.SetComment("Preprocessor AliTPC data base entries.");

	Bool_t storeOK = Store("Calib", "Temperature", fTemp, &metaData, 0, kFALSE);
        if ( !storeOK )  result=1;

   }

   return result;
}
//______________________________________________________________________________________________
UInt_t AliTPCPreprocessor::MapPressure(TMap* dcsAliasMap)
{

   // extract DCS temperature maps. Perform fits to save space

  UInt_t result=0;
  TMap *map = fPressure->ExtractDCS(dcsAliasMap);
  if (map) {
    fPressure->MakeSplineFit(map);
    AliInfo(Form("Pressure values extracted, fits performed.\n"));
  } else {
    AliError(Form("No atmospheric pressure map extracted.\n"));
    Log("AliTPCPreprocsessor: no atmospheric pressure map extracted. \n");
    result=9;
  }
  delete map;
  // Now store the final CDB file

  if ( result == 0 ) {
        AliCDBMetaData metaData;
	metaData.SetBeamPeriod(0);
	metaData.SetResponsible("Haavard Helstrup");
	metaData.SetComment("Preprocessor AliTPC data base entries.");

	Bool_t storeOK = Store("Calib", "Pressure", fPressure, &metaData, 0, 0);
        if ( !storeOK ) result=1;

   }

   return result;
}
//______________________________________________________________________________________________
UInt_t AliTPCPreprocessor::ExtractPedestals()
{
 //
 //  Read pedestal file from file exchage server
 //  Keep original entry from OCDB in case no new pedestals are available
 //
 AliTPCCalPad *calPadPed=0;
 AliCDBEntry* entry = GetFromOCDB("Calib", "Pedestals");
 if (entry) calPadPed = (AliTPCCalPad*)entry->GetObject();
 if ( calPadPed==NULL ) {
     AliWarning(Form("No previous TPC pedestal entry available.\n"));
     Log("AliTPCPreprocsessor: No previous TPC pedestal entry available.\n");
     calPadPed = new AliTPCCalPad();
 }

 UInt_t result=0;

 Int_t nSectors = fROC->GetNSectors();
 TList* list = GetFileSources(AliShuttleInterface::kDAQ,"pedestals");
 if (list) {

//  loop through all files from LDCs

    UInt_t index = 0;
    while (list->At(index)!=NULL) {
     TObjString* fileNameEntry = (TObjString*) list->At(index);
     if (fileNameEntry!=NULL) {
        TString fileName = GetFile(AliShuttleInterface::kDAQ, "pedestals",
	                                 fileNameEntry->GetString().Data());
        TFile *f = TFile::Open(fileName);
        AliTPCCalibPedestal *calPed;
	f->GetObject("AliTPCCalibPedestal",calPed);

        //  replace entries for the sectors available in the present file

        for (Int_t sector=0; sector<=nSectors; sector++) {
           AliTPCCalROC *roc=calPed->GetCalRocPedestal(sector, kFALSE);
           if ( roc )  calPadPed->SetCalROC(roc,sector);
        }
      }
     ++index;
    }  // while(list)
//
//  Store updated pedestal entry to OCDB
//
    AliCDBMetaData metaData;
    metaData.SetBeamPeriod(0);
    metaData.SetResponsible("Haavard Helstrup");
    metaData.SetComment("Preprocessor AliTPC data base entries.");

    Bool_t storeOK = Store("Calib", "Pedestals", calPadPed, &metaData, 0, kTRUE);
    if ( !storeOK ) result=1;

  }  // if(list)
  return result;
}
<commit_msg>Wrong constructor called (Haavard)<commit_after>/**************************************************************************
 * Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved.      *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * 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 "AliTPCPreprocessor.h"
#include "AliShuttleInterface.h"

#include "AliCDBMetaData.h"
#include "AliDCSValue.h"
#include "AliLog.h"
#include "AliTPCSensorTempArray.h"
#include "AliTPCROC.h"
#include "AliTPCCalROC.h"
#include "AliTPCCalPad.h"
#include "AliTPCCalibPedestal.h"
#include "TFile.h"

#include <TTimeStamp.h>

const Int_t kValCutTemp = 100;               // discard temperatures > 100 degrees
const Int_t kDiffCutTemp = 5;	             // discard temperature differences > 5 degrees
const TString kPedestalRunType = "PEDESTAL_RUN";  // pedestal run identifier

//
// This class is the SHUTTLE preprocessor for the TPC detector.
// It contains several components, this far the part containing
// temperatures is implemented
//

ClassImp(AliTPCPreprocessor)

//______________________________________________________________________________________________
AliTPCPreprocessor::AliTPCPreprocessor(AliShuttleInterface* shuttle) :
  AliPreprocessor("TPC",shuttle),
  fTemp(0), fPressure(0), fConfigOK(kTRUE), fROC(0)
{
  // constructor
  fROC = AliTPCROC::Instance();
}
//______________________________________________________________________________________________
// AliTPCPreprocessor::AliTPCPreprocessor(const AliTPCPreprocessor& org) :
//   AliPreprocessor(org),
//   fTemp(0), fPressure(0), fConfigOK(kTRUE)
// {
//   // copy constructor not implemented
//   //   -- missing underlying copy constructor in AliPreprocessor
//
//   Fatal("AliTPCPreprocessor", "copy constructor not implemented");
//
// //  fTemp = new AliTPCSensorTempArray(*(org.fTemp));
// }

//______________________________________________________________________________________________
AliTPCPreprocessor::~AliTPCPreprocessor()
{
  // destructor

  delete fTemp;
  delete fPressure;
}
//______________________________________________________________________________________________
AliTPCPreprocessor& AliTPCPreprocessor::operator = (const AliTPCPreprocessor& )
{
  Fatal("operator =", "assignment operator not implemented");
  return *this;
}

//______________________________________________________________________________________________
void AliTPCPreprocessor::Initialize(Int_t run, UInt_t startTime,
	UInt_t endTime)
{
  // Creates AliTestDataDCS object

  AliPreprocessor::Initialize(run, startTime, endTime);

	AliInfo(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run,
		TTimeStamp(startTime).AsString(),
		TTimeStamp(endTime).AsString()));

  // Temperature sensors

        TTree *confTree = 0;
	AliCDBEntry* entry = GetFromOCDB("Config", "Temperature");
        if (entry) confTree = (TTree*) entry->GetObject();
        if ( confTree==0 ) {
           AliError(Form("Temperature Config OCDB entry missing.\n"));
           Log("AliTPCPreprocsessor: Temperature Config OCDB entry missing.\n");
	   fConfigOK = kFALSE;
	   return;
        }
        fTemp = new AliTPCSensorTempArray(fStartTime, fEndTime, confTree);
	fTemp->SetValCut(kValCutTemp);
	fTemp->SetDiffCut(kDiffCutTemp);

  // Pressure sensors

        confTree=0;
	entry=0;
	entry = GetFromOCDB("Config", "Pressure");
        if (entry) confTree = (TTree*) entry->GetObject();
        if ( confTree==0 ) {
           AliError(Form("Pressure Config OCDB entry missing.\n"));
           Log("AliTPCPreprocsessor: Pressure Config OCDB entry missing.\n");
	   fConfigOK = kFALSE;
	   return;
        }
	fPressure = new AliDCSSensorArray(fStartTime, fEndTime, confTree);

}

//______________________________________________________________________________________________
UInt_t AliTPCPreprocessor::Process(TMap* dcsAliasMap)
{
  // Fills data into TPC calibrations objects

  // Amanda servers provide information directly through dcsAliasMap

  if (!dcsAliasMap) return 9;
  if (!fConfigOK) return 9;

  TString runType = GetRunType();

  // Temperature sensors are processed by AliTPCCalTemp

  UInt_t tempResult = MapTemperature(dcsAliasMap);
  UInt_t result=tempResult;

  // Pressure sensors

  UInt_t pressureResult = MapPressure(dcsAliasMap);
  result += pressureResult;

  // Other calibration information will be retrieved through FXS files
  //  examples:
  //    TList* fileSourcesDAQ = GetFile(AliShuttleInterface::kDAQ, "pedestals");
  //    const char* fileNamePed = GetFile(AliShuttleInterface::kDAQ, "pedestals", "LDC1");
  //
  //    TList* fileSourcesHLT = GetFile(AliShuttleInterface::kHLT, "calib");
  //    const char* fileNameHLT = GetFile(AliShuttleInterface::kHLT, "calib", "LDC1");

  if(runType == kPedestalRunType) {
    UInt_t pedestalResult = ExtractPedestals();
    result += pedestalResult;
  }

  return result;
}
//______________________________________________________________________________________________
UInt_t AliTPCPreprocessor::MapTemperature(TMap* dcsAliasMap)
{

   // extract DCS temperature maps. Perform fits to save space

  UInt_t result=0;
  TMap *map = fTemp->ExtractDCS(dcsAliasMap);
  if (map) {
    fTemp->MakeSplineFit(map);
    AliInfo(Form("Temperature values extracted, fits performed.\n"));
  } else {
    AliError(Form("No temperature map extracted.\n"));
    Log("AliTPCPreprocsessor: no temperature map extracted. \n");
    result=9;
  }
  delete map;
  // Now store the final CDB file

  if ( result == 0 ) {
        AliCDBMetaData metaData;
	metaData.SetBeamPeriod(0);
	metaData.SetResponsible("Haavard Helstrup");
	metaData.SetComment("Preprocessor AliTPC data base entries.");

	Bool_t storeOK = Store("Calib", "Temperature", fTemp, &metaData, 0, kFALSE);
        if ( !storeOK )  result=1;

   }

   return result;
}
//______________________________________________________________________________________________
UInt_t AliTPCPreprocessor::MapPressure(TMap* dcsAliasMap)
{

   // extract DCS temperature maps. Perform fits to save space

  UInt_t result=0;
  TMap *map = fPressure->ExtractDCS(dcsAliasMap);
  if (map) {
    fPressure->MakeSplineFit(map);
    AliInfo(Form("Pressure values extracted, fits performed.\n"));
  } else {
    AliError(Form("No atmospheric pressure map extracted.\n"));
    Log("AliTPCPreprocsessor: no atmospheric pressure map extracted. \n");
    result=9;
  }
  delete map;
  // Now store the final CDB file

  if ( result == 0 ) {
        AliCDBMetaData metaData;
	metaData.SetBeamPeriod(0);
	metaData.SetResponsible("Haavard Helstrup");
	metaData.SetComment("Preprocessor AliTPC data base entries.");

	Bool_t storeOK = Store("Calib", "Pressure", fPressure, &metaData, 0, 0);
        if ( !storeOK ) result=1;

   }

   return result;
}
//______________________________________________________________________________________________
UInt_t AliTPCPreprocessor::ExtractPedestals()
{
 //
 //  Read pedestal file from file exchage server
 //  Keep original entry from OCDB in case no new pedestals are available
 //
 AliTPCCalPad *calPadPed=0;
 AliCDBEntry* entry = GetFromOCDB("Calib", "Pedestals");
 if (entry) calPadPed = (AliTPCCalPad*)entry->GetObject();
 if ( calPadPed==NULL ) {
     AliWarning(Form("No previous TPC pedestal entry available.\n"));
     Log("AliTPCPreprocsessor: No previous TPC pedestal entry available.\n");
     calPadPed = new AliTPCCalPad("pedestals","pedestals");
 }

 UInt_t result=0;

 Int_t nSectors = fROC->GetNSectors();
 TList* list = GetFileSources(AliShuttleInterface::kDAQ,"pedestals");
 if (list) {

//  loop through all files from LDCs

    UInt_t index = 0;
    while (list->At(index)!=NULL) {
     TObjString* fileNameEntry = (TObjString*) list->At(index);
     if (fileNameEntry!=NULL) {
        TString fileName = GetFile(AliShuttleInterface::kDAQ, "pedestals",
	                                 fileNameEntry->GetString().Data());
        TFile *f = TFile::Open(fileName);
        AliTPCCalibPedestal *calPed;
	f->GetObject("AliTPCCalibPedestal",calPed);

        //  replace entries for the sectors available in the present file

        for (Int_t sector=0; sector<=nSectors; sector++) {
           AliTPCCalROC *roc=calPed->GetCalRocPedestal(sector, kFALSE);
           if ( roc )  calPadPed->SetCalROC(roc,sector);
        }
      }
     ++index;
    }  // while(list)
//
//  Store updated pedestal entry to OCDB
//
    AliCDBMetaData metaData;
    metaData.SetBeamPeriod(0);
    metaData.SetResponsible("Haavard Helstrup");
    metaData.SetComment("Preprocessor AliTPC data base entries.");

    Bool_t storeOK = Store("Calib", "Pedestals", calPadPed, &metaData, 0, kTRUE);
    if ( !storeOK ) result=1;

  }  // if(list)
  return result;
}
<|endoftext|>


<commit_before>//===- AsmWriterInst.h - Classes encapsulating a printable inst -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// These classes implement a parser for assembly strings.
//
//===----------------------------------------------------------------------===//

#include "AsmWriterInst.h"
#include "CodeGenTarget.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"

using namespace llvm;

static bool isIdentChar(char C) {
  return (C >= 'a' && C <= 'z') ||
  (C >= 'A' && C <= 'Z') ||
  (C >= '0' && C <= '9') ||
  C == '_';
}

std::string AsmWriterOperand::getCode() const {
  if (OperandType == isLiteralTextOperand) {
    if (Str.size() == 1)
      return "O << '" + Str + "'; ";
    return "O << \"" + Str + "\"; ";
  }

  if (OperandType == isLiteralStatementOperand)
    return Str;

  std::string Result = Str + "(MI";
  if (MIOpNo != ~0U)
    Result += ", " + utostr(MIOpNo);
  Result += ", O";
  if (!MiModifier.empty())
    Result += ", \"" + MiModifier + '"';
  return Result + "); ";
}

/// ParseAsmString - Parse the specified Instruction's AsmString into this
/// AsmWriterInst.
///
AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
                             unsigned Variant,
                             int FirstOperandColumn,
                             int OperandSpacing) {
  this->CGI = &CGI;

  // This is the number of tabs we've seen if we're doing columnar layout.
  unsigned CurColumn = 0;

  // NOTE: Any extensions to this code need to be mirrored in the
  // AsmPrinter::printInlineAsm code that executes as compile time (assuming
  // that inline asm strings should also get the new feature)!
  std::string AsmString = CGI.FlattenAsmStringVariants(CGI.AsmString, Variant);
  std::string::size_type LastEmitted = 0;
  while (LastEmitted != AsmString.size()) {
    std::string::size_type DollarPos =
      AsmString.find_first_of("$\\", LastEmitted);
    if (DollarPos == std::string::npos) DollarPos = AsmString.size();

    // Emit a constant string fragment.
    if (DollarPos != LastEmitted) {
      for (; LastEmitted != DollarPos; ++LastEmitted)
        switch (AsmString[LastEmitted]) {
          case '\n':
            AddLiteralString("\\n");
            break;
          case '\t':
            // If the asm writer is not using a columnar layout, \t is not
            // magic.
            if (FirstOperandColumn == -1 || OperandSpacing == -1) {
              AddLiteralString("\\t");
            } else {
              // We recognize a tab as an operand delimeter.
              unsigned DestColumn = FirstOperandColumn +
              CurColumn++ * OperandSpacing;
              Operands.push_back(
                AsmWriterOperand(
                  "O.PadToColumn(" +
                  utostr(DestColumn) + ");\n",
                  AsmWriterOperand::isLiteralStatementOperand));
            }
            break;
          case '"':
            AddLiteralString("\\\"");
            break;
          case '\\':
            AddLiteralString("\\\\");
            break;
          default:
            AddLiteralString(std::string(1, AsmString[LastEmitted]));
            break;
        }
    } else if (AsmString[DollarPos] == '\\') {
      if (DollarPos+1 != AsmString.size()) {
        if (AsmString[DollarPos+1] == 'n') {
          AddLiteralString("\\n");
        } else if (AsmString[DollarPos+1] == 't') {
          // If the asm writer is not using a columnar layout, \t is not
          // magic.
          if (FirstOperandColumn == -1 || OperandSpacing == -1) {
            AddLiteralString("\\t");
            break;
          }

          // We recognize a tab as an operand delimeter.
          unsigned DestColumn = FirstOperandColumn +
          CurColumn++ * OperandSpacing;
          Operands.push_back(
            AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n",
                             AsmWriterOperand::isLiteralStatementOperand));
          break;
        } else if (std::string("${|}\\").find(AsmString[DollarPos+1])
                   != std::string::npos) {
          AddLiteralString(std::string(1, AsmString[DollarPos+1]));
        } else {
          PrintFatalError("Non-supported escaped character found in instruction '" +
            CGI.TheDef->getName() + "'!");
        }
        LastEmitted = DollarPos+2;
        continue;
      }
    } else if (DollarPos+1 != AsmString.size() &&
               AsmString[DollarPos+1] == '$') {
      AddLiteralString("$");  // "$$" -> $
      LastEmitted = DollarPos+2;
    } else {
      // Get the name of the variable.
      std::string::size_type VarEnd = DollarPos+1;

      // handle ${foo}bar as $foo by detecting whether the character following
      // the dollar sign is a curly brace.  If so, advance VarEnd and DollarPos
      // so the variable name does not contain the leading curly brace.
      bool hasCurlyBraces = false;
      if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) {
        hasCurlyBraces = true;
        ++DollarPos;
        ++VarEnd;
      }

      while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
        ++VarEnd;
      std::string VarName(AsmString.begin()+DollarPos+1,
                          AsmString.begin()+VarEnd);

      // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed
      // into printOperand.  Also support ${:feature}, which is passed into
      // PrintSpecial.
      std::string Modifier;

      // In order to avoid starting the next string at the terminating curly
      // brace, advance the end position past it if we found an opening curly
      // brace.
      if (hasCurlyBraces) {
        if (VarEnd >= AsmString.size())
          PrintFatalError("Reached end of string before terminating curly brace in '"
            + CGI.TheDef->getName() + "'");

        // Look for a modifier string.
        if (AsmString[VarEnd] == ':') {
          ++VarEnd;
          if (VarEnd >= AsmString.size())
            PrintFatalError("Reached end of string before terminating curly brace in '"
              + CGI.TheDef->getName() + "'");

          unsigned ModifierStart = VarEnd;
          while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
            ++VarEnd;
          Modifier = std::string(AsmString.begin()+ModifierStart,
                                 AsmString.begin()+VarEnd);
          if (Modifier.empty())
            PrintFatalError("Bad operand modifier name in '"+ CGI.TheDef->getName() + "'");
        }

        if (AsmString[VarEnd] != '}')
          PrintFatalError("Variable name beginning with '{' did not end with '}' in '"
            + CGI.TheDef->getName() + "'");
        ++VarEnd;
      }
      if (VarName.empty() && Modifier.empty())
        PrintFatalError("Stray '$' in '" + CGI.TheDef->getName() +
          "' asm string, maybe you want $$?");

      if (VarName.empty()) {
        // Just a modifier, pass this into PrintSpecial.
        Operands.push_back(AsmWriterOperand("PrintSpecial",
                                            ~0U,
                                            ~0U,
                                            Modifier));
      } else {
        // Otherwise, normal operand.
        unsigned OpNo = CGI.Operands.getOperandNamed(VarName);
        CGIOperandList::OperandInfo OpInfo = CGI.Operands[OpNo];

        unsigned MIOp = OpInfo.MIOperandNo;
        Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName,
                                            OpNo, MIOp, Modifier));
      }
      LastEmitted = VarEnd;
    }
  }

  Operands.push_back(AsmWriterOperand("return;",
    AsmWriterOperand::isLiteralStatementOperand));
}

/// MatchesAllButOneOp - If this instruction is exactly identical to the
/// specified instruction except for one differing operand, return the differing
/// operand number.  If more than one operand mismatches, return ~1, otherwise
/// if the instructions are identical return ~0.
unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{
  if (Operands.size() != Other.Operands.size()) return ~1;

  unsigned MismatchOperand = ~0U;
  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
    if (Operands[i] != Other.Operands[i]) {
      if (MismatchOperand != ~0U)  // Already have one mismatch?
        return ~1U;
      else
        MismatchOperand = i;
    }
  }
  return MismatchOperand;
}
<commit_msg>Remove 'else' after 'return'. No functional change.<commit_after>//===- AsmWriterInst.h - Classes encapsulating a printable inst -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// These classes implement a parser for assembly strings.
//
//===----------------------------------------------------------------------===//

#include "AsmWriterInst.h"
#include "CodeGenTarget.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"

using namespace llvm;

static bool isIdentChar(char C) {
  return (C >= 'a' && C <= 'z') ||
  (C >= 'A' && C <= 'Z') ||
  (C >= '0' && C <= '9') ||
  C == '_';
}

std::string AsmWriterOperand::getCode() const {
  if (OperandType == isLiteralTextOperand) {
    if (Str.size() == 1)
      return "O << '" + Str + "'; ";
    return "O << \"" + Str + "\"; ";
  }

  if (OperandType == isLiteralStatementOperand)
    return Str;

  std::string Result = Str + "(MI";
  if (MIOpNo != ~0U)
    Result += ", " + utostr(MIOpNo);
  Result += ", O";
  if (!MiModifier.empty())
    Result += ", \"" + MiModifier + '"';
  return Result + "); ";
}

/// ParseAsmString - Parse the specified Instruction's AsmString into this
/// AsmWriterInst.
///
AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
                             unsigned Variant,
                             int FirstOperandColumn,
                             int OperandSpacing) {
  this->CGI = &CGI;

  // This is the number of tabs we've seen if we're doing columnar layout.
  unsigned CurColumn = 0;

  // NOTE: Any extensions to this code need to be mirrored in the
  // AsmPrinter::printInlineAsm code that executes as compile time (assuming
  // that inline asm strings should also get the new feature)!
  std::string AsmString = CGI.FlattenAsmStringVariants(CGI.AsmString, Variant);
  std::string::size_type LastEmitted = 0;
  while (LastEmitted != AsmString.size()) {
    std::string::size_type DollarPos =
      AsmString.find_first_of("$\\", LastEmitted);
    if (DollarPos == std::string::npos) DollarPos = AsmString.size();

    // Emit a constant string fragment.
    if (DollarPos != LastEmitted) {
      for (; LastEmitted != DollarPos; ++LastEmitted)
        switch (AsmString[LastEmitted]) {
          case '\n':
            AddLiteralString("\\n");
            break;
          case '\t':
            // If the asm writer is not using a columnar layout, \t is not
            // magic.
            if (FirstOperandColumn == -1 || OperandSpacing == -1) {
              AddLiteralString("\\t");
            } else {
              // We recognize a tab as an operand delimeter.
              unsigned DestColumn = FirstOperandColumn +
              CurColumn++ * OperandSpacing;
              Operands.push_back(
                AsmWriterOperand(
                  "O.PadToColumn(" +
                  utostr(DestColumn) + ");\n",
                  AsmWriterOperand::isLiteralStatementOperand));
            }
            break;
          case '"':
            AddLiteralString("\\\"");
            break;
          case '\\':
            AddLiteralString("\\\\");
            break;
          default:
            AddLiteralString(std::string(1, AsmString[LastEmitted]));
            break;
        }
    } else if (AsmString[DollarPos] == '\\') {
      if (DollarPos+1 != AsmString.size()) {
        if (AsmString[DollarPos+1] == 'n') {
          AddLiteralString("\\n");
        } else if (AsmString[DollarPos+1] == 't') {
          // If the asm writer is not using a columnar layout, \t is not
          // magic.
          if (FirstOperandColumn == -1 || OperandSpacing == -1) {
            AddLiteralString("\\t");
            break;
          }

          // We recognize a tab as an operand delimeter.
          unsigned DestColumn = FirstOperandColumn +
          CurColumn++ * OperandSpacing;
          Operands.push_back(
            AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n",
                             AsmWriterOperand::isLiteralStatementOperand));
          break;
        } else if (std::string("${|}\\").find(AsmString[DollarPos+1])
                   != std::string::npos) {
          AddLiteralString(std::string(1, AsmString[DollarPos+1]));
        } else {
          PrintFatalError("Non-supported escaped character found in instruction '" +
            CGI.TheDef->getName() + "'!");
        }
        LastEmitted = DollarPos+2;
        continue;
      }
    } else if (DollarPos+1 != AsmString.size() &&
               AsmString[DollarPos+1] == '$') {
      AddLiteralString("$");  // "$$" -> $
      LastEmitted = DollarPos+2;
    } else {
      // Get the name of the variable.
      std::string::size_type VarEnd = DollarPos+1;

      // handle ${foo}bar as $foo by detecting whether the character following
      // the dollar sign is a curly brace.  If so, advance VarEnd and DollarPos
      // so the variable name does not contain the leading curly brace.
      bool hasCurlyBraces = false;
      if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) {
        hasCurlyBraces = true;
        ++DollarPos;
        ++VarEnd;
      }

      while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
        ++VarEnd;
      std::string VarName(AsmString.begin()+DollarPos+1,
                          AsmString.begin()+VarEnd);

      // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed
      // into printOperand.  Also support ${:feature}, which is passed into
      // PrintSpecial.
      std::string Modifier;

      // In order to avoid starting the next string at the terminating curly
      // brace, advance the end position past it if we found an opening curly
      // brace.
      if (hasCurlyBraces) {
        if (VarEnd >= AsmString.size())
          PrintFatalError("Reached end of string before terminating curly brace in '"
            + CGI.TheDef->getName() + "'");

        // Look for a modifier string.
        if (AsmString[VarEnd] == ':') {
          ++VarEnd;
          if (VarEnd >= AsmString.size())
            PrintFatalError("Reached end of string before terminating curly brace in '"
              + CGI.TheDef->getName() + "'");

          unsigned ModifierStart = VarEnd;
          while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
            ++VarEnd;
          Modifier = std::string(AsmString.begin()+ModifierStart,
                                 AsmString.begin()+VarEnd);
          if (Modifier.empty())
            PrintFatalError("Bad operand modifier name in '"+ CGI.TheDef->getName() + "'");
        }

        if (AsmString[VarEnd] != '}')
          PrintFatalError("Variable name beginning with '{' did not end with '}' in '"
            + CGI.TheDef->getName() + "'");
        ++VarEnd;
      }
      if (VarName.empty() && Modifier.empty())
        PrintFatalError("Stray '$' in '" + CGI.TheDef->getName() +
          "' asm string, maybe you want $$?");

      if (VarName.empty()) {
        // Just a modifier, pass this into PrintSpecial.
        Operands.push_back(AsmWriterOperand("PrintSpecial",
                                            ~0U,
                                            ~0U,
                                            Modifier));
      } else {
        // Otherwise, normal operand.
        unsigned OpNo = CGI.Operands.getOperandNamed(VarName);
        CGIOperandList::OperandInfo OpInfo = CGI.Operands[OpNo];

        unsigned MIOp = OpInfo.MIOperandNo;
        Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName,
                                            OpNo, MIOp, Modifier));
      }
      LastEmitted = VarEnd;
    }
  }

  Operands.push_back(AsmWriterOperand("return;",
    AsmWriterOperand::isLiteralStatementOperand));
}

/// MatchesAllButOneOp - If this instruction is exactly identical to the
/// specified instruction except for one differing operand, return the differing
/// operand number.  If more than one operand mismatches, return ~1, otherwise
/// if the instructions are identical return ~0.
unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{
  if (Operands.size() != Other.Operands.size()) return ~1;

  unsigned MismatchOperand = ~0U;
  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
    if (Operands[i] != Other.Operands[i]) {
      if (MismatchOperand != ~0U)  // Already have one mismatch?
        return ~1U;
      MismatchOperand = i;
    }
  }
  return MismatchOperand;
}
<|endoftext|>


<commit_before>#include "eval.hpp"

#include <functional>
#include <stdexcept>

#include "ast.hpp"
#include "hamt.hpp"
#include "symbol.hpp"
#include "common.hpp"

namespace eval {

using table_type = hamt::map<symbol, value>;

template<class T>
using monad = std::function<T(const table_type&)>;

static monad<value> compile(ast::expr self);

template<class T>
static monad<value> compile(T self) {
  throw std::runtime_error("unimplemented compile: " + std::string(typeid(T).name()));
}

static monad<value> compile(ast::lit self) {
  return match(self, [](auto self) -> monad<value> {
    return [=](const auto&) { return self; };
  });
}

struct closure {
  table_type env;
  symbol arg;
  monad<value> body;
};

static monad<value> compile(ast::abs self) {
  return [body = compile(self.body),
          arg = self.arg.name](const auto& env) {
    return closure{env, arg, body};
  };
}

static monad<value> compile(ast::app self) {
  const auto func = compile(self.func);
  const auto arg = compile(self.arg);

  return [=](const auto& env) {
    const value f = func(env);
    const closure& c = f.template get<closure>();
    return c.body(c.env.set(c.arg, arg(env)));
  };
}

static monad<value> compile(ast::var self) {
  return [name=self.name](const auto& env) {
    return env.get(name);
  };
}

static monad<value> compile(ast::cond self) {
  return [pred=compile(self.pred),
          conseq=compile(self.conseq),
          alt=compile(self.alt)](const auto& env) {
    if(pred(env).template get<bool>()) {
      return conseq(env);
    } else {
      return alt(env);
    }
  };
}

struct def {
  symbol name;
  monad<value> code;
};

static monad<value> compile(ast::let self) {
  const auto defs = map(self.defs, [](ast::def self) {
    return def{self.name, compile(self.value)};
  });

  const auto body = compile(self.body);

  return [=](auto env) {
    for(auto&& def: defs) {
      env = env.set(def.name, def.code(env));
    }

    return body(env);
  };
}

struct record {
  using attrs_type = hamt::map<symbol, value>;
  attrs_type attrs;
};

static monad<value> compile(ast::record self) {
  const auto defs = map(self.attrs, [](ast::def self) {
    return def{self.name, compile(self.value)};
  });

  return [defs](const auto& env) {
    record res;
    for(auto&& attr: defs) {
      res.attrs = std::move(res.attrs).set(attr.name, attr.code(env));
    }
    return res;
  };
}

static monad<value> compile(ast::attr self) {
  auto arg = compile(self.arg);
  auto name = self.name;
  return [=](const auto& env) {
    return arg(env).template get<record>().attrs.get(name);
  };
}

std::string value::show() const {
  return match(*this,
               [](bool self) -> std::string { return self ? "true" : "false"; },
               [](long self) { return std::to_string(self); },
               [](double self) { return std::to_string(self); },
               [](std::string self) { return quote(self); },
               [](record self) {
                 std::stringstream ss;
                 ss << "(record";

                 self.attrs.iter([&](symbol name, value val) {
                   ss << " (" << name << " " << val.show() << ")";
                 });

                 ss << ")";

                 // TODO abbreviate if too long
                 return ss.str();
               },
               [](closure self) { return std::string("#closure"); });
}

static monad<value> compile(ast::expr self) {
  return match(self, [](auto self) { return compile(self); });
}

static value wrap(value self) { return self; }

template<class Func>
static closure wrap(Func func) {
  const symbol arg = "__arg__";
  return {{}, arg, [=](const auto& env) {
    return wrap(func(env.get(arg)));
  }};
}

struct environment {
  table_type table;

  template<class T>
  void def(symbol name, T value) {
    table = table.set(name, wrap(value));
  }
};

value run(std::shared_ptr<environment> env, const ast::expr& self) {
  return compile(self)(env->table);
}

std::shared_ptr<environment> make_environment() {
  auto res = std::make_shared<environment>();

  res->def("eq", [=](value x) {
    return [=](value y) -> value {
      return x.get<long>() == y.get<long>();
    };
  });

  res->def("add", [=](value x) {
    return [=](value y) -> value {
      return x.get<long>() + y.get<long>();
    };
  });

  res->def("sub", [=](value x) {
    return [=](value y) -> value {
      return x.get<long>() - y.get<long>();
    };
  });

  res->def("mul", [=](value x) {
    return [=](value y) -> value {
      return x.get<long>() * y.get<long>();
    };
  });

  return res;
}

} // namespace eval

<commit_msg>eval recursive functions<commit_after>#include "eval.hpp"

#include <functional>
#include <stdexcept>

#include "ast.hpp"
#include "hamt.hpp"
#include "symbol.hpp"
#include "common.hpp"

namespace eval {

using table_type = hamt::map<symbol, value>;

template<class T>
using monad = std::function<T(const table_type&)>;

static monad<value> compile(ast::expr self);

template<class T>
static monad<value> compile(T self) {
  throw std::runtime_error("unimplemented compile: " + std::string(typeid(T).name()));
}

static monad<value> compile(ast::lit self) {
  return match(self, [](auto self) -> monad<value> {
    return [=](const auto&) { return self; };
  });
}

struct closure {
  table_type env;
  symbol arg;
  monad<value> body;
  mutable symbol self = "__self__";
};

static symbol gensym(std::string prefix) {
  static std::size_t index = 0;
  symbol res = (prefix + std::to_string(index++)).c_str();
  return res;
}

static monad<value> compile(ast::abs self) {
  return [body = compile(self.body),
          arg = self.arg.name](const auto& env) {
    return closure{env, arg, body};
  };
}

static monad<value> compile(ast::app self) {
  const auto func = compile(self.func);
  const auto arg = compile(self.arg);

  return [=](const auto& env) {
    value f = func(env);
    const closure& c = f.template get<closure>();
    auto sub = c.env.set(c.arg, arg(env));

    // TODO only if needed
    sub = sub.set(c.self, std::move(f));
    return c.body(sub);
  };
}

static monad<value> compile(ast::var self) {
  return [name=self.name](const auto& env) {
    return env.get(name);
  };
}

static monad<value> compile(ast::cond self) {
  return [pred=compile(self.pred),
          conseq=compile(self.conseq),
          alt=compile(self.alt)](const auto& env) {
    if(pred(env).template get<bool>()) {
      return conseq(env);
    } else {
      return alt(env);
    }
  };
}

struct def {
  symbol name;
  monad<value> code;
};

static monad<value> compile(ast::let self) {
  const auto defs = map(self.defs, [](ast::def self) {
    return def{self.name, compile(self.value)};
  });

  const auto body = compile(self.body);

  return [=](auto env) {
    for(auto&& def: defs) {
      value v = def.code(env);
      if(auto c = v.template cast<closure>()) {
        c->self = def.name;
      }
      env = env.set(def.name, std::move(v));
    }

    return body(env);
  };
}

struct record {
  using attrs_type = hamt::map<symbol, value>;
  attrs_type attrs;
};

static monad<value> compile(ast::record self) {
  const auto defs = map(self.attrs, [](ast::def self) {
    return def{self.name, compile(self.value)};
  });

  return [defs](const auto& env) {
    record res;
    for(auto&& attr: defs) {
      res.attrs = std::move(res.attrs).set(attr.name, attr.code(env));
    }
    return res;
  };
}

static monad<value> compile(ast::attr self) {
  auto arg = compile(self.arg);
  auto name = self.name;
  return [=](const auto& env) {
    return arg(env).template get<record>().attrs.get(name);
  };
}

std::string value::show() const {
  return match(*this,
               [](bool self) -> std::string { return self ? "true" : "false"; },
               [](long self) { return std::to_string(self); },
               [](double self) { return std::to_string(self); },
               [](std::string self) { return quote(self); },
               [](record self) {
                 std::stringstream ss;
                 ss << "(record";

                 self.attrs.iter([&](symbol name, value val) {
                   ss << " (" << name << " " << val.show() << ")";
                 });

                 ss << ")";

                 // TODO abbreviate if too long
                 return ss.str();
               },
               [](closure self) { return std::string("#closure"); });
}

static monad<value> compile(ast::expr self) {
  return match(self, [](auto self) { return compile(self); });
}

static value wrap(value self) { return self; }

template<class Func>
static closure wrap(Func func) {
  const symbol arg = "__arg__";
  return {{}, arg, [=](const auto& env) {
    return wrap(func(env.get(arg)));
  }};
}

struct environment {
  table_type table;

  template<class T>
  void def(symbol name, T value) {
    table = table.set(name, wrap(value));
  }
};

value run(std::shared_ptr<environment> env, const ast::expr& self) {
  return compile(self)(env->table);
}

std::shared_ptr<environment> make_environment() {
  auto res = std::make_shared<environment>();

  res->def("eq", [=](value x) {
    return [=](value y) -> value {
      return x.get<long>() == y.get<long>();
    };
  });

  res->def("add", [=](value x) {
    return [=](value y) -> value {
      return x.get<long>() + y.get<long>();
    };
  });

  res->def("sub", [=](value x) {
    return [=](value y) -> value {
      return x.get<long>() - y.get<long>();
    };
  });

  res->def("mul", [=](value x) {
    return [=](value y) -> value {
      return x.get<long>() * y.get<long>();
    };
  });

  return res;
}

} // namespace eval

<|endoftext|>


<commit_before>//===-- sanitizer_symbolizer_mac.cc ---------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is shared between various sanitizers' runtime libraries.
//
// Implementation of Mac-specific "atos" symbolizer.
//===----------------------------------------------------------------------===//

#include "sanitizer_platform.h"
#if SANITIZER_MAC

#include "sanitizer_allocator_internal.h"
#include "sanitizer_mac.h"
#include "sanitizer_symbolizer_mac.h"

namespace __sanitizer {

#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <util.h>

bool DlAddrSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
  Dl_info info;
  int result = dladdr((const void *)addr, &info);
  if (!result) return false;
  const char *demangled = DemangleCXXABI(info.dli_sname);
  stack->info.function = demangled ? internal_strdup(demangled) : nullptr;
  return true;
}

bool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) {
  Dl_info info;
  int result = dladdr((const void *)addr, &info);
  if (!result) return false;
  const char *demangled = DemangleCXXABI(info.dli_sname);
  datainfo->name = internal_strdup(demangled);
  datainfo->start = (uptr)info.dli_saddr;
  return true;
}

class AtosSymbolizerProcess : public SymbolizerProcess {
 public:
  explicit AtosSymbolizerProcess(const char *path, pid_t parent_pid)
      : SymbolizerProcess(path, /*use_forkpty*/ true) {
    // Put the string command line argument in the object so that it outlives
    // the call to GetArgV.
    internal_snprintf(pid_str_, sizeof(pid_str_), "%d", parent_pid);
  }

 private:
  bool ReachedEndOfOutput(const char *buffer, uptr length) const override {
    return (length >= 1 && buffer[length - 1] == '\n');
  }

  void GetArgV(const char *path_to_binary,
               const char *(&argv)[kArgVMax]) const override {
    int i = 0;
    argv[i++] = path_to_binary;
    argv[i++] = "-p";
    argv[i++] = &pid_str_[0];
    if (GetMacosVersion() == MACOS_VERSION_MAVERICKS) {
      // On Mavericks atos prints a deprecation warning which we suppress by
      // passing -d. The warning isn't present on other OSX versions, even the
      // newer ones.
      argv[i++] = "-d";
    }
    argv[i++] = nullptr;
  }

  char pid_str_[16];
};

static const char *kAtosErrorMessages[] = {
  "atos cannot examine process",
  "unable to get permission to examine process",
  "An admin user name and password is required",
  "could not load inserted library",
  "architecture mismatch between analysis process",
};

static bool IsAtosErrorMessage(const char *str) {
  for (uptr i = 0; i < ARRAY_SIZE(kAtosErrorMessages); i++) {
    if (internal_strstr(str, kAtosErrorMessages[i])) {
      return true;
    }
  }
  return false;
}

static bool ParseCommandOutput(const char *str, uptr addr, char **out_name,
                               char **out_module, char **out_file, uptr *line,
                               uptr *start_address) {
  // Trim ending newlines.
  char *trim;
  ExtractTokenUpToDelimiter(str, "\n", &trim);

  // The line from `atos` is in one of these formats:
  //   myfunction (in library.dylib) (sourcefile.c:17)
  //   myfunction (in library.dylib) + 0x1fe
  //   myfunction (in library.dylib) + 15
  //   0xdeadbeef (in library.dylib) + 0x1fe
  //   0xdeadbeef (in library.dylib) + 15
  //   0xdeadbeef (in library.dylib)
  //   0xdeadbeef

  if (IsAtosErrorMessage(trim)) {
    Report("atos returned an error: %s\n", trim);
    InternalFree(trim);
    return false;
  }

  const char *rest = trim;
  char *symbol_name;
  rest = ExtractTokenUpToDelimiter(rest, " (in ", &symbol_name);
  if (internal_strncmp(symbol_name, "0x", 2) != 0)
    *out_name = symbol_name;
  else
    InternalFree(symbol_name);
  rest = ExtractTokenUpToDelimiter(rest, ") ", out_module);

  if (rest[0] == '(') {
    if (out_file) {
      rest++;
      rest = ExtractTokenUpToDelimiter(rest, ":", out_file);
      char *extracted_line_number;
      rest = ExtractTokenUpToDelimiter(rest, ")", &extracted_line_number);
      if (line) *line = (uptr)internal_atoll(extracted_line_number);
      InternalFree(extracted_line_number);
    }
  } else if (rest[0] == '+') {
    rest += 2;
    uptr offset = internal_atoll(rest);
    if (start_address) *start_address = addr - offset;
  }

  InternalFree(trim);
  return true;
}

AtosSymbolizer::AtosSymbolizer(const char *path, LowLevelAllocator *allocator)
    : process_(new(*allocator) AtosSymbolizerProcess(path, getpid())) {}

bool AtosSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
  if (!process_) return false;
  char command[32];
  internal_snprintf(command, sizeof(command), "0x%zx\n", addr);
  const char *buf = process_->SendCommand(command);
  if (!buf) return false;
  uptr line;
  if (!ParseCommandOutput(buf, addr, &stack->info.function, &stack->info.module,
                          &stack->info.file, &line, nullptr)) {
    process_ = nullptr;
    return false;
  }
  stack->info.line = (int)line;
  return true;
}

bool AtosSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
  if (!process_) return false;
  char command[32];
  internal_snprintf(command, sizeof(command), "0x%zx\n", addr);
  const char *buf = process_->SendCommand(command);
  if (!buf) return false;
  if (!ParseCommandOutput(buf, addr, &info->name, &info->module, nullptr,
                          nullptr, &info->start)) {
    process_ = nullptr;
    return false;
  }
  return true;
}

}  // namespace __sanitizer

#endif  // SANITIZER_MAC
<commit_msg>[sanitizer] Detect an invalid answer in AtosSymbolizer<commit_after>//===-- sanitizer_symbolizer_mac.cc ---------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is shared between various sanitizers' runtime libraries.
//
// Implementation of Mac-specific "atos" symbolizer.
//===----------------------------------------------------------------------===//

#include "sanitizer_platform.h"
#if SANITIZER_MAC

#include "sanitizer_allocator_internal.h"
#include "sanitizer_mac.h"
#include "sanitizer_symbolizer_mac.h"

namespace __sanitizer {

#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <util.h>

bool DlAddrSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
  Dl_info info;
  int result = dladdr((const void *)addr, &info);
  if (!result) return false;
  const char *demangled = DemangleCXXABI(info.dli_sname);
  stack->info.function = demangled ? internal_strdup(demangled) : nullptr;
  return true;
}

bool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) {
  Dl_info info;
  int result = dladdr((const void *)addr, &info);
  if (!result) return false;
  const char *demangled = DemangleCXXABI(info.dli_sname);
  datainfo->name = internal_strdup(demangled);
  datainfo->start = (uptr)info.dli_saddr;
  return true;
}

class AtosSymbolizerProcess : public SymbolizerProcess {
 public:
  explicit AtosSymbolizerProcess(const char *path, pid_t parent_pid)
      : SymbolizerProcess(path, /*use_forkpty*/ true) {
    // Put the string command line argument in the object so that it outlives
    // the call to GetArgV.
    internal_snprintf(pid_str_, sizeof(pid_str_), "%d", parent_pid);
  }

 private:
  bool ReachedEndOfOutput(const char *buffer, uptr length) const override {
    return (length >= 1 && buffer[length - 1] == '\n');
  }

  void GetArgV(const char *path_to_binary,
               const char *(&argv)[kArgVMax]) const override {
    int i = 0;
    argv[i++] = path_to_binary;
    argv[i++] = "-p";
    argv[i++] = &pid_str_[0];
    if (GetMacosVersion() == MACOS_VERSION_MAVERICKS) {
      // On Mavericks atos prints a deprecation warning which we suppress by
      // passing -d. The warning isn't present on other OSX versions, even the
      // newer ones.
      argv[i++] = "-d";
    }
    argv[i++] = nullptr;
  }

  char pid_str_[16];
};

static const char *kAtosErrorMessages[] = {
  "atos cannot examine process",
  "unable to get permission to examine process",
  "An admin user name and password is required",
  "could not load inserted library",
  "architecture mismatch between analysis process",
};

static bool IsAtosErrorMessage(const char *str) {
  for (uptr i = 0; i < ARRAY_SIZE(kAtosErrorMessages); i++) {
    if (internal_strstr(str, kAtosErrorMessages[i])) {
      return true;
    }
  }
  return false;
}

static bool ParseCommandOutput(const char *str, uptr addr, char **out_name,
                               char **out_module, char **out_file, uptr *line,
                               uptr *start_address) {
  // Trim ending newlines.
  char *trim;
  ExtractTokenUpToDelimiter(str, "\n", &trim);

  // The line from `atos` is in one of these formats:
  //   myfunction (in library.dylib) (sourcefile.c:17)
  //   myfunction (in library.dylib) + 0x1fe
  //   myfunction (in library.dylib) + 15
  //   0xdeadbeef (in library.dylib) + 0x1fe
  //   0xdeadbeef (in library.dylib) + 15
  //   0xdeadbeef (in library.dylib)
  //   0xdeadbeef

  if (IsAtosErrorMessage(trim)) {
    Report("atos returned an error: %s\n", trim);
    InternalFree(trim);
    return false;
  }

  const char *rest = trim;
  char *symbol_name;
  rest = ExtractTokenUpToDelimiter(rest, " (in ", &symbol_name);
  if (rest[0] == '\0') {
    InternalFree(symbol_name);
    InternalFree(trim);
    return false;
  }

  if (internal_strncmp(symbol_name, "0x", 2) != 0)
    *out_name = symbol_name;
  else
    InternalFree(symbol_name);
  rest = ExtractTokenUpToDelimiter(rest, ") ", out_module);

  if (rest[0] == '(') {
    if (out_file) {
      rest++;
      rest = ExtractTokenUpToDelimiter(rest, ":", out_file);
      char *extracted_line_number;
      rest = ExtractTokenUpToDelimiter(rest, ")", &extracted_line_number);
      if (line) *line = (uptr)internal_atoll(extracted_line_number);
      InternalFree(extracted_line_number);
    }
  } else if (rest[0] == '+') {
    rest += 2;
    uptr offset = internal_atoll(rest);
    if (start_address) *start_address = addr - offset;
  }

  InternalFree(trim);
  return true;
}

AtosSymbolizer::AtosSymbolizer(const char *path, LowLevelAllocator *allocator)
    : process_(new(*allocator) AtosSymbolizerProcess(path, getpid())) {}

bool AtosSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
  if (!process_) return false;
  char command[32];
  internal_snprintf(command, sizeof(command), "0x%zx\n", addr);
  const char *buf = process_->SendCommand(command);
  if (!buf) return false;
  uptr line;
  if (!ParseCommandOutput(buf, addr, &stack->info.function, &stack->info.module,
                          &stack->info.file, &line, nullptr)) {
    process_ = nullptr;
    return false;
  }
  stack->info.line = (int)line;
  return true;
}

bool AtosSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
  if (!process_) return false;
  char command[32];
  internal_snprintf(command, sizeof(command), "0x%zx\n", addr);
  const char *buf = process_->SendCommand(command);
  if (!buf) return false;
  if (!ParseCommandOutput(buf, addr, &info->name, &info->module, nullptr,
                          nullptr, &info->start)) {
    process_ = nullptr;
    return false;
  }
  return true;
}

}  // namespace __sanitizer

#endif  // SANITIZER_MAC
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <string>
#include <ctime>
#include "jsoncpp/json.h"

using namespace std;

const int MAX_N = 25;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

bool invalid[MAX_N][MAX_N];
int n, m;

struct Point {
	int x, y;
	Point(const int &_x, const int &_y)
		: x(_x), y(_y)
	{}
};

list<Point> snake[2]; // 0ʾԼߣ1ʾԷ
int possibleDire[10];
int posCount;

bool whetherGrow(int num)  //غǷ
{
	if (num <= 9) return true;
	if ((num - 9) % 3 == 0) return true;
	return false;
}

void deleteEnd(int id)     //ɾβ
{
	snake[id].pop_back();
}

void move(int id, int dire, int num)  //Ϊid߳direƶһ
{
	Point p = *(snake[id].begin());
	int x = p.x + dx[dire];
	int y = p.y + dy[dire];
	snake[id].push_front(Point(x, y));
	if (!whetherGrow(num))
		deleteEnd(id);
}
void outputSnakeBody(int id)    //
{
	cout << "Snake No." << id << endl;
	for (list<Point>::iterator iter = snake[id].begin(); iter != snake[id].end(); ++iter)
		cout << iter->x << " " << iter->y << endl;
	cout << endl;
}

bool isInBody(int x, int y)   //ж(x,y)λǷ
{
	for (int id = 0; id <= 1; id++)
		for (list<Point>::iterator iter = snake[id].begin(); iter != snake[id].end(); ++iter)
			if (x == iter->x && y == iter->y)
				return true;
	return false;
}

bool validDirection(int id, int k)  //жϵǰƶһǷϷ
{
	Point p = *(snake[id].begin());
	int x = p.x + dx[k];
	int y = p.y + dy[k];
	if (x > n || y > m || x < 1 || y < 1) return false;
	if (invalid[x][y]) return false;
	if (isInBody(x, y)) return false;
	return true;
}

int canPass[MAX_N][MAX_N] = {0};

void MaintainMap()
{

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			if (invalid[i][j]) {
				canPass[i][j] = 100000;
			} else {
				canPass[i][j] = 0;
			}
		}
	}
	for (int id = 0; id <= 1; id++) {
		int len = 1;
		for (list<Point>::iterator iter = snake[id].begin(); iter != snake[id].end(); ++iter, ++len) {
			canPass[iter->x][iter->y] = len;
		}
	}
}

int BFS(const int &sX, const int &sY)
{
	bool vis[MAX_N][MAX_N] = {0};
	vector<Point> que;
	que.push_back(Point(sX, sY));
	vis[sX][sY] = true;
	for (int i = 0; i < que.size(); ++i) {
		int uX = que[i].x;
		int uY = que[i].y;
		for (int i = 0; i < 4; ++i) {
			int tX = uX + dx[i];
			int tY = uY + dy[i];
			if (tX > n || tY > m || tX < 1 || tY < 1) {
				continue;
			}
			if (canPass[tX][tY]) {
				continue;
			}
			if (!vis[tX][tY]) {
				vis[tX][tY] = true;
				que.push_back(Point(tX, tY));
			}
		}
	}
	return que.size();
}

int CurHeadDirection(int id)
{
	list<Point>::iterator iter = snake[id].begin();
	Point head = *iter++;
	Point next = *iter;
	if (head.x == next.x) {
		if (head.y == next.y + 1) {
			return 1;
		} else {
			return 3;
		}
	} else {
		if (head.x == next.y + 1) {
			return 2;
		} else {
			return 0;
		}
	}
}

int MakeDecision(Json::Value &ret)
{
	MaintainMap();
	vector<int> consider;
	int bestCnt = 0;
	int headX = snake[0].begin()->x;
	int headY = snake[0].begin()->y;
	for (int dir = 0; dir < 4; ++dir) {
		if (validDirection(0, dir)) {
			int sX = headX + dx[dir];
			int sY = headY + dy[dir];
			int result = BFS(sX, sY);
			ret["response"]["debug"][char(dir + '0')]["result"] = result;
			if (bestCnt < result) {
				consider.clear();
				consider.push_back(dir);
				bestCnt = result;
			} else if (bestCnt == result) {
				consider.push_back(dir);
			}
		}
	}
	int cur = CurHeadDirection(0);
	if (consider.size() > 1) {
		for (int i = 0; i < consider.size(); ++i) {
			if (consider[i] == cur) {
				continue;
			}
			return consider[i];
		}
	}
	return consider.front();
}

int main()
{
	memset(invalid, 0, sizeof(invalid));
	string str;
	string temp;
	while (getline(cin, temp))
		str += temp;

	Json::Reader reader;
	Json::Value input;
	reader.parse(str, input);

	n = input["requests"][(Json::Value::UInt) 0]["height"].asInt();  //̸߶
	m = input["requests"][(Json::Value::UInt) 0]["width"].asInt();   //̿

	int x = input["requests"][(Json::Value::UInt) 0]["x"].asInt();  //߳ʼϢ
	if (x == 1) {
		snake[0].push_front(Point(1, 1));
		snake[1].push_front(Point(n, m));
	} else {
		snake[1].push_front(Point(1, 1));
		snake[0].push_front(Point(n, m));
	}
	//ͼеϰ
	int obsCount = input["requests"][(Json::Value::UInt) 0]["obstacle"].size();

	for (int i = 0; i < obsCount; i++) {
		int ox = input["requests"][(Json::Value::UInt) 0]["obstacle"][(Json::Value::UInt) i]["x"].asInt();
		int oy = input["requests"][(Json::Value::UInt) 0]["obstacle"][(Json::Value::UInt) i]["y"].asInt();
		invalid[ox][oy] = 1;
	}

	//ʷϢֳָ
	int total = input["responses"].size();

	int dire;
	for (int i = 0; i < total; i++) {
		dire = input["responses"][i]["direction"].asInt();
		move(0, dire, i);

		dire = input["requests"][i + 1]["direction"].asInt();
		move(1, dire, i);
	}

	if (!whetherGrow(total)) // غ
	{
		deleteEnd(0);
		deleteEnd(1);
	}

	Json::Value ret;
	ret["response"]["direction"] = MakeDecision(ret);

	Json::FastWriter writer;
	cout << writer.write(ret) << endl;

	return 0;
}<commit_msg>use a stupid method to make decision<commit_after>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sstream>
#include <list>
#include <queue>
#include <string>
#include <ctime>
#include "jsoncpp/json.h"

using namespace std;

const int MAX_N = 25;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

bool invalid[MAX_N][MAX_N];
int n, m;

struct Point {
	int x, y;
	Point(const int &_x, const int &_y)
		: x(_x), y(_y)
	{}
};

list<Point> snake[2]; // 0ʾԼߣ1ʾԷ
int possibleDire[10];
int posCount;

bool whetherGrow(int num)  //غǷ
{
	if (num <= 9) return true;
	if ((num - 9) % 3 == 0) return true;
	return false;
}

void deleteEnd(int id)     //ɾβ
{
	snake[id].pop_back();
}

void move(int id, int dire, int num)  //Ϊid߳direƶһ
{
	Point p = *(snake[id].begin());
	int x = p.x + dx[dire];
	int y = p.y + dy[dire];
	snake[id].push_front(Point(x, y));
	if (!whetherGrow(num))
		deleteEnd(id);
}
void outputSnakeBody(int id)    //
{
	cout << "Snake No." << id << endl;
	for (list<Point>::iterator iter = snake[id].begin(); iter != snake[id].end(); ++iter)
		cout << iter->x << " " << iter->y << endl;
	cout << endl;
}

bool isInBody(int x, int y)   //ж(x,y)λǷ
{
	for (int id = 0; id <= 1; id++)
		for (list<Point>::iterator iter = snake[id].begin(); iter != snake[id].end(); ++iter)
			if (x == iter->x && y == iter->y)
				return true;
	return false;
}

bool validDirection(int id, int k)  //жϵǰƶһǷϷ
{
	Point p = *(snake[id].begin());
	int x = p.x + dx[k];
	int y = p.y + dy[k];
	if (x > n || y > m || x < 1 || y < 1) return false;
	if (invalid[x][y]) return false;
	if (isInBody(x, y)) return false;
	return true;
}

int canPass[MAX_N][MAX_N] = {0};

void MaintainMap()
{
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			if (invalid[i][j]) {
				canPass[i][j] = 100000;
			} else {
				canPass[i][j] = 0;
			}
		}
	}
	for (int id = 0; id <= 1; id++) {
		int len = 1;
		for (list<Point>::iterator iter = snake[id].begin(); iter != snake[id].end(); ++iter) {
			canPass[iter->x][iter->y] = len++;
		}
	}
}

int BFS(const int &sX, const int &sY)
{
	bool vis[MAX_N][MAX_N] = {0};
	queue<Point> que;
	que.push(Point(sX, sY));
	vis[sX][sY] = true;
	int cnt = 1;
	while (!que.empty()) {
		for (int i = 0; i < 4; ++i) {
			int tX = que.front().x + dx[i];
			int tY = que.front().y + dy[i];
			if (tX < 1 || tY < 1 || tX > n || tY > m || canPass[tX][tY] > 0) {
				continue;
			}
			if (!vis[tX][tY]) {
				vis[tX][tY] = true;
				++cnt;
				que.push(Point(tX, tY));
			}
		}
		que.pop();
	}
	return cnt;
}

int CurHeadDirection(int id)
{
	list<Point>::iterator iter = snake[id].begin();
	Point head = *iter++;
	Point next = *iter;
	if (head.x == next.x) {
		if (head.y == next.y + 1) {
			return 1;
		} else {
			return 3;
		}
	} else {
		if (head.x == next.y + 1) {
			return 2;
		} else {
			return 0;
		}
	}
}

int MakeDecision(Json::Value &ret)
{
	MaintainMap();
	vector<int> consider;
	int bestCnt = 0;
	int headX = snake[0].begin()->x;
	int headY = snake[0].begin()->y;
	int cnt = 0;
	for (int dir = 0; dir < 4; ++dir) {
		if (validDirection(0, dir)) {
			int sX = headX + dx[dir];
			int sY = headY + dy[dir];
			int result = BFS(sX, sY);
			ostringstream oss;
			oss << "BFS at (" << sX << "," << sY << ") with empty unit " << result;
			ret["response"]["debug"][cnt++] = oss.str().c_str();
			if (bestCnt < result) {
				consider.clear();
				consider.push_back(dir);
				bestCnt = result;
			} else if (bestCnt == result) {
				consider.push_back(dir);
			}
		}
	}
	srand((unsigned)time(NULL));
	return consider[rand() % consider.size()];
}

int main()
{
	memset(invalid, 0, sizeof(invalid));
	string str;
	string temp;
	while (getline(cin, temp))
		str += temp;

	Json::Reader reader;
	Json::Value input;
	reader.parse(str, input);

	n = input["requests"][(Json::Value::UInt) 0]["height"].asInt();  //̸߶
	m = input["requests"][(Json::Value::UInt) 0]["width"].asInt();   //̿

	int x = input["requests"][(Json::Value::UInt) 0]["x"].asInt();  //߳ʼϢ
	if (x == 1) {
		snake[0].push_front(Point(1, 1));
		snake[1].push_front(Point(n, m));
	} else {
		snake[1].push_front(Point(1, 1));
		snake[0].push_front(Point(n, m));
	}
	//ͼеϰ
	int obsCount = input["requests"][(Json::Value::UInt) 0]["obstacle"].size();

	for (int i = 0; i < obsCount; i++) {
		int ox = input["requests"][(Json::Value::UInt) 0]["obstacle"][(Json::Value::UInt) i]["x"].asInt();
		int oy = input["requests"][(Json::Value::UInt) 0]["obstacle"][(Json::Value::UInt) i]["y"].asInt();
		invalid[ox][oy] = 1;
	}

	//ʷϢֳָ
	int total = input["responses"].size();

	int dire;
	for (int i = 0; i < total; i++) {
		dire = input["responses"][i]["direction"].asInt();
		move(0, dire, i);

		dire = input["requests"][i + 1]["direction"].asInt();
		move(1, dire, i);
	}

	if (!whetherGrow(total)) // غ
	{
		deleteEnd(0);
		deleteEnd(1);
	}

	Json::Value ret;
	ret["response"]["direction"] = MakeDecision(ret);

	Json::FastWriter writer;
	cout << writer.write(ret) << endl;

	return 0;
}<|endoftext|>


<commit_before>/*
 *  Renderer.cpp
 *  BasicScreenObject_Test
 *
 *  Created by Matthias Rohrbach 2 on 12.06.12.
 *  Copyright 2012 rob & rose grafik. All rights reserved.
 *
 */

#include "Renderer.h"

Renderer::Renderer(){
	myname			="Renderer";
	nextPickingName	= 100;
	cursorsize		= 10;
	maxcursors		= 20;
	captureincrement= 2;
	mapsampling		= 2;

	touchtomouse = true;
	mousetotouch = true;
	mousetouchid = -1;

	currentviewport	= ofRectangle(0,0,0,0);

	bTuioSetup			= false;
	bColorPickerSetup	= false;
	isRenderer			= true;
	drawcursors			= true;
}

Renderer::~Renderer(){

}

void Renderer::setup(){

	ofAddListener(ofEvents().mousePressed, this, &Renderer::mousePressed);
	ofAddListener(ofEvents().mouseDragged, this, &Renderer::mouseDragged);
	ofAddListener(ofEvents().mouseReleased, this, &Renderer::mouseReleased);

	ofAddListener(ofEvents().touchDown,this,&Renderer::tuioAdded);
	ofAddListener(ofEvents().touchUp,this,&Renderer::tuioRemoved);
	ofAddListener(ofEvents().touchMoved,this,&Renderer::tuioUpdated);
}

void Renderer::setupColorPicker(float _width, float _height, float _sampling, float _increment){

	BasicScreenObject::setSize(_width,_height);
	mapsampling			= _sampling;
	captureincrement	= _increment;
	mapscale			= 1.0f/(float)mapsampling;

	ofFbo::Settings s;

	s.width				= getWidth()/mapsampling;
	s.height			= getHeight()/mapsampling;
	s.internalformat	= GL_RGB;
	s.useDepth			= true;

	pickingmap.allocate(s );
	maxbounds = ofRectangle ( 0 , 0 , pickingmap.getWidth()-1 , pickingmap.getHeight()-1 ) ;
	camera.setupPerspective();

	bColorPickerSetup=true;
}

void Renderer::update(){

	Tweener.update();

	if(bColorPickerSetup){

		bool waslighting = glIsEnabled(GL_LIGHTING);
		if(waslighting){
			glDisable(GL_LIGHTING);
		}

		if(ofGetFrameNum() % captureincrement==0){
			pickingmap.begin();

			ofClear(0);
			ofPushMatrix() ;
			ofScale( mapscale , mapscale , mapscale) ;
			BasicScreenObject::drawForPicking();
			ofPopMatrix();

			pickingmap.end();
			pickingmap.readToPixels(mapPixels);
		}

		if(waslighting){
			glEnable(GL_LIGHTING);
		}
	}
}

void Renderer::draw(){

	currentviewport = ofGetCurrentViewport();
	camera.begin();
	BasicScreenObject::draw();
	camera.end();
	if (drawcursors) drawCursors();
}

void Renderer::_draw(){

}

void Renderer::startTuio(int _port) {
	port = _port;
	tuio.connect(_port);
	bTuioSetup = true;
}

void Renderer::tuioAdded(ofTouchEventArgs & _cursor) {

	if (touchtomouse && mousetouchid==-1) {
		mousetouchid = _cursor.id;

		static ofMouseEventArgs mouseEventArgs;
		mouseEventArgs.x = _cursor.x*ofGetWidth();
		mouseEventArgs.y = _cursor.y*ofGetHeight();
		mouseEventArgs.button = 1;
		lastfakemouseevent = &mouseEventArgs;
		ofNotifyEvent( ofEvents().mousePressed, mouseEventArgs );

	}

	notifyObjects(_cursor.x*ofGetWidth(), _cursor.y*ofGetHeight(), _cursor.id, MT_ADD);
}

void Renderer::tuioRemoved(ofTouchEventArgs & _cursor){

	if (touchtomouse && mousetouchid==_cursor.id) {
		mousetouchid = -1;

		static ofMouseEventArgs mouseEventArgs;
		mouseEventArgs.x = _cursor.x*ofGetWidth();
		mouseEventArgs.y = _cursor.y*ofGetHeight();
		mouseEventArgs.button = 1;
		lastfakemouseevent = &mouseEventArgs;
		ofNotifyEvent( ofEvents().mouseReleased , mouseEventArgs );
	}

	notifyObjects(_cursor.x*ofGetWidth(), _cursor.y*ofGetHeight(), _cursor.id, MT_REMOVE);
}

void Renderer::tuioUpdated(ofTouchEventArgs & _cursor){

	if (touchtomouse && mousetouchid==_cursor.id) {
		static ofMouseEventArgs mouseEventArgs;
		mouseEventArgs.x = _cursor.x*ofGetWidth();
		mouseEventArgs.y = _cursor.y*ofGetHeight();
		mouseEventArgs.button = 1;
		lastfakemouseevent = &mouseEventArgs;
		ofNotifyEvent( ofEvents().mouseDragged, mouseEventArgs );
	}

	notifyObjects(_cursor.x*ofGetWidth(), _cursor.y*ofGetHeight(), _cursor.id, MT_UPDATE);
}

void Renderer::mousePressed(ofMouseEventArgs& _cursor){
	if (mousetotouch) {
		// ignore this mouse-event, if it was created by emulating a mouse-event from a touch
		if (lastfakemouseevent != &_cursor) {
			notifyObjects(_cursor.x, _cursor.y, -1, MT_ADD);
		}
	}
}

void Renderer::mouseReleased(ofMouseEventArgs& _cursor){
	if (mousetotouch) {
		// ignore this mouse-event, if it was created by emulating a mouse-event from a touch
		if (lastfakemouseevent != &_cursor) {
			notifyObjects(_cursor.x, _cursor.y, -1, MT_REMOVE);
		}
	}
}

void Renderer::mouseDragged(ofMouseEventArgs& _cursor){
	if (mousetotouch) {
		// ignore this mouse-event, if it was created by emulating a mouse-event from a touch
		if (lastfakemouseevent != &_cursor) {
			notifyObjects(_cursor.x, _cursor.y, -1, MT_UPDATE);
		}
	}
}

void Renderer::notifyObjects(float _screenx, float _screeny,int _fingerid, int _action){

	mtRay ray;
	ray.pos = camera.screenToWorld(ofVec3f(_screenx,_screeny,-1),currentviewport);
	ray.dir = camera.screenToWorld(ofVec3f(_screenx,_screeny,1), currentviewport)-ray.pos;
	ray.screenpos.set(_screenx, _screeny);

	BasicInteractiveObject* overobj=(BasicInteractiveObject*)getObjectAt(_screenx, _screeny);

	for(int i=0;i<pickingObjects.size();i++){
		BasicInteractiveObject* obj =(BasicInteractiveObject*) pickingObjects[i];
		if (obj != NULL && obj!=overobj) {
			switch (_action) {
				case (MT_ADD) : {
					obj->touchDownOutside(ray,_fingerid);
					break;
				}
				case (MT_UPDATE) : {
					obj->touchMovedOutside(ray,_fingerid);
					break;
				}
				case (MT_REMOVE) : {
					obj->touchUpOutside(ray,_fingerid);
					break;
				}
			}
		}
	}

	if(overobj!=NULL){
		switch (_action) {
			case (MT_ADD) : {
				overobj->touchDownOnMe(ray,_fingerid);
				break;
			}
			case (MT_UPDATE) : {
				overobj->touchMovedOnMe(ray,_fingerid);
				break;
			}
			case (MT_REMOVE) : {
				overobj->touchUpOnMe(ray,_fingerid);
				break;
			}
		}
	}

	lastinteraction=ofGetElapsedTimeMillis();
}

void Renderer::drawMap() {
	ofSetColor(255, 255, 255);
	pickingmap.draw(0, 0,pickingmap.getWidth(),pickingmap.getHeight());
}

void Renderer::drawCursors(){

	ofEnableAlphaBlending();
	glBlendFunc(GL_ONE, GL_ONE);

	if(bTuioSetup){
		std::list<TuioCursor*> cursorList =  tuio.client->getTuioCursors();
		std::list<TuioCursor*>::iterator tit;
		tuio.client->lockCursorList();

		for (tit = cursorList.begin(); tit != cursorList.end(); tit++) {
			TuioCursor * cur = (*tit);
			glColor3f(0.1,0.1, 0.1);
			for(int i = 0; i < 5; i++){
				ofEllipse(cur->getX()*ofGetWidth(),
						  cur->getY()*ofGetHeight(),
						  20.0+i*i,
						  20.0+i*i);
			}
		}
		tuio.client->unlockCursorList();
	}

	if (mousetotouch) {
		if (ofGetMousePressed()) {
			glColor3f(0.1,0.1, 0.1);
			for(int i = 0; i < 5; i++){
				ofEllipse(ofGetMouseX(),
						  ofGetMouseY(),
						  20.0+i*i,
						  20.0+i*i);
			}
		}
	}

	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
}

BasicScreenObject* Renderer::getObjectAt(float _screenx, float _screeny){
	int fbox	=_screenx/mapsampling;
	int fboy	=_screeny/mapsampling;
	fbox		= ofClamp(fbox, 0, maxbounds.width);
	fboy		= ofClamp(fboy, 0, maxbounds.height);

	int index	= (fbox + fboy * pickingmap.getWidth()) * 3 ;

	ofColor	fboc			= ofColor( mapPixels[index] , mapPixels[index + 1] , mapPixels[index + 2] );
	GLint pickingName		= colorToPickingName(fboc);
	BasicScreenObject* obj	= NULL;

	if (pickingObjects.find(pickingName) != pickingObjects.end()) {
		obj = pickingObjects[pickingName];
	}
	return obj;
}

GLuint Renderer::getNextPickingName(BasicInteractiveObject* _object) {
	GLuint np = ++nextPickingName;
	pickingObjects[np] = _object;
	return np;
}

long Renderer::lastInteractionMillis(){
	return lastinteraction;
}

void Renderer::isDrawCursors(bool _drawCursors) {
	drawcursors = _drawCursors;
}

<commit_msg>some performance tests in renderer…<commit_after>/*
 *  Renderer.cpp
 *  BasicScreenObject_Test
 *
 *  Created by Matthias Rohrbach 2 on 12.06.12.
 *  Copyright 2012 rob & rose grafik. All rights reserved.
 *
 */

#include "Renderer.h"

Renderer::Renderer(){
	myname			="Renderer";
	nextPickingName	= 100;
	cursorsize		= 10;
	maxcursors		= 20;
	captureincrement= 2;
	mapsampling		= 2;

	touchtomouse = true;
	mousetotouch = true;
	mousetouchid = -1;

	currentviewport	= ofRectangle(0,0,0,0);

	bTuioSetup			= false;
	bColorPickerSetup	= false;
	isRenderer			= true;
	drawcursors			= true;
}

Renderer::~Renderer(){

}

void Renderer::setup(){

	ofAddListener(ofEvents().mousePressed, this, &Renderer::mousePressed);
	ofAddListener(ofEvents().mouseDragged, this, &Renderer::mouseDragged);
	ofAddListener(ofEvents().mouseReleased, this, &Renderer::mouseReleased);

	ofAddListener(ofEvents().touchDown,this,&Renderer::tuioAdded);
	ofAddListener(ofEvents().touchUp,this,&Renderer::tuioRemoved);
	ofAddListener(ofEvents().touchMoved,this,&Renderer::tuioUpdated);
}

void Renderer::setupColorPicker(float _width, float _height, float _sampling, float _increment){

	BasicScreenObject::setSize(_width,_height);
	mapsampling			= _sampling;
	captureincrement	= _increment;
	mapscale			= 1.0f/(float)mapsampling;

	ofFbo::Settings s;

	s.width				= getWidth()  / mapsampling;
	s.height			= getHeight() / mapsampling;
	//s.internalformat	= GL_LUMINANCE32F_ARB;
	s.internalformat	= GL_RGB; // would be much faster using GL_LUMINANCE or GL_LUMINANCE32F_ARB (32bit resolution should be enough);
	s.useDepth			= true;

	pickingmap.allocate(s );
	maxbounds = ofRectangle ( 0 , 0 , pickingmap.getWidth()-1 , pickingmap.getHeight()-1 ) ;
	camera.setupPerspective();

	bColorPickerSetup=true;
}

void Renderer::update(){
	//int startTime = ofGetElapsedTimeMillis();

	Tweener.update();

	if(bColorPickerSetup){

		bool waslighting = glIsEnabled(GL_LIGHTING);
		if(waslighting){
			glDisable(GL_LIGHTING);
		}

		if(ofGetFrameNum() % captureincrement==0){
			pickingmap.begin();

			ofClear(0);
			ofPushMatrix() ;
			ofScale( mapscale , mapscale , mapscale) ;
			BasicScreenObject::drawForPicking();
			ofPopMatrix();

			pickingmap.end();
			pickingmap.readToPixels(mapPixels);					// < takes 20ms for rgb fbo. 1ms for GL_LUMINANCE
			//ofLog(OF_LOG_NOTICE, ofToString(mapPixels.size()));
		}

		if(waslighting){
			glEnable(GL_LIGHTING);
		}
	}

	//ofLog(OF_LOG_NOTICE, "update: " + ofToString(ofGetElapsedTimeMillis()-startTime));
}

void Renderer::draw(){

	//int startTime = ofGetElapsedTimeMillis();

	currentviewport = ofGetCurrentViewport();
	camera.begin();
	BasicScreenObject::draw();
	camera.end();
	if (drawcursors) drawCursors();

	//ofLog(OF_LOG_NOTICE, "draw: " + ofToString(ofGetElapsedTimeMillis()-startTime));
}

void Renderer::_draw(){

}

void Renderer::startTuio(int _port) {
	port = _port;
	tuio.connect(_port);
	bTuioSetup = true;
}

void Renderer::tuioAdded(ofTouchEventArgs & _cursor) {

	if (touchtomouse && mousetouchid==-1) {
		mousetouchid = _cursor.id;

		static ofMouseEventArgs mouseEventArgs;
		mouseEventArgs.x = _cursor.x*ofGetWidth();
		mouseEventArgs.y = _cursor.y*ofGetHeight();
		mouseEventArgs.button = 1;
		lastfakemouseevent = &mouseEventArgs;
		ofNotifyEvent( ofEvents().mousePressed, mouseEventArgs );

	}

	notifyObjects(_cursor.x*ofGetWidth(), _cursor.y*ofGetHeight(), _cursor.id, MT_ADD);
}

void Renderer::tuioRemoved(ofTouchEventArgs & _cursor){

	if (touchtomouse && mousetouchid==_cursor.id) {
		mousetouchid = -1;

		static ofMouseEventArgs mouseEventArgs;
		mouseEventArgs.x = _cursor.x*ofGetWidth();
		mouseEventArgs.y = _cursor.y*ofGetHeight();
		mouseEventArgs.button = 1;
		lastfakemouseevent = &mouseEventArgs;
		ofNotifyEvent( ofEvents().mouseReleased , mouseEventArgs );
	}

	notifyObjects(_cursor.x*ofGetWidth(), _cursor.y*ofGetHeight(), _cursor.id, MT_REMOVE);
}

void Renderer::tuioUpdated(ofTouchEventArgs & _cursor){

	if (touchtomouse && mousetouchid==_cursor.id) {
		static ofMouseEventArgs mouseEventArgs;
		mouseEventArgs.x = _cursor.x*ofGetWidth();
		mouseEventArgs.y = _cursor.y*ofGetHeight();
		mouseEventArgs.button = 1;
		lastfakemouseevent = &mouseEventArgs;
		ofNotifyEvent( ofEvents().mouseDragged, mouseEventArgs );
	}

	notifyObjects(_cursor.x*ofGetWidth(), _cursor.y*ofGetHeight(), _cursor.id, MT_UPDATE);
}

void Renderer::mousePressed(ofMouseEventArgs& _cursor){
	if (mousetotouch) {
		// ignore this mouse-event, if it was created by emulating a mouse-event from a touch
		if (lastfakemouseevent != &_cursor) {
			notifyObjects(_cursor.x, _cursor.y, -1, MT_ADD);
		}
	}
}

void Renderer::mouseReleased(ofMouseEventArgs& _cursor){
	if (mousetotouch) {
		// ignore this mouse-event, if it was created by emulating a mouse-event from a touch
		if (lastfakemouseevent != &_cursor) {
			notifyObjects(_cursor.x, _cursor.y, -1, MT_REMOVE);
		}
	}
}

void Renderer::mouseDragged(ofMouseEventArgs& _cursor){
	if (mousetotouch) {
		// ignore this mouse-event, if it was created by emulating a mouse-event from a touch
		if (lastfakemouseevent != &_cursor) {
			notifyObjects(_cursor.x, _cursor.y, -1, MT_UPDATE);
		}
	}
}

void Renderer::notifyObjects(float _screenx, float _screeny,int _fingerid, int _action){

	mtRay ray;
	ray.pos = camera.screenToWorld(ofVec3f(_screenx,_screeny,-1),currentviewport);
	ray.dir = camera.screenToWorld(ofVec3f(_screenx,_screeny,1), currentviewport)-ray.pos;
	ray.screenpos.set(_screenx, _screeny);

	BasicInteractiveObject* overobj=(BasicInteractiveObject*)getObjectAt(_screenx, _screeny);

	for(int i=0;i<pickingObjects.size();i++){
		BasicInteractiveObject* obj =(BasicInteractiveObject*) pickingObjects[i];
		if (obj != NULL && obj!=overobj) {
			switch (_action) {
				case (MT_ADD) : {
					obj->touchDownOutside(ray,_fingerid);
					break;
				}
				case (MT_UPDATE) : {
					obj->touchMovedOutside(ray,_fingerid);
					break;
				}
				case (MT_REMOVE) : {
					obj->touchUpOutside(ray,_fingerid);
					break;
				}
			}
		}
	}

	if(overobj!=NULL){
		switch (_action) {
			case (MT_ADD) : {
				overobj->touchDownOnMe(ray,_fingerid);
				break;
			}
			case (MT_UPDATE) : {
				overobj->touchMovedOnMe(ray,_fingerid);
				break;
			}
			case (MT_REMOVE) : {
				overobj->touchUpOnMe(ray,_fingerid);
				break;
			}
		}
	}

	lastinteraction=ofGetElapsedTimeMillis();
}

void Renderer::drawMap() {
	ofSetColor(255, 255, 255);
	pickingmap.draw(0, 0,pickingmap.getWidth(),pickingmap.getHeight());
}

void Renderer::drawCursors(){

	ofEnableAlphaBlending();
	glBlendFunc(GL_ONE, GL_ONE);

	if(bTuioSetup){
		std::list<TuioCursor*> cursorList =  tuio.client->getTuioCursors();
		std::list<TuioCursor*>::iterator tit;
		tuio.client->lockCursorList();

		for (tit = cursorList.begin(); tit != cursorList.end(); tit++) {
			TuioCursor * cur = (*tit);
			glColor3f(0.1,0.1, 0.1);
			for(int i = 0; i < 5; i++){
				ofEllipse(cur->getX()*ofGetWidth(),
						  cur->getY()*ofGetHeight(),
						  20.0+i*i,
						  20.0+i*i);
			}
		}
		tuio.client->unlockCursorList();
	}

	if (mousetotouch) {
		if (ofGetMousePressed()) {
			glColor3f(0.1,0.1, 0.1);
			for(int i = 0; i < 5; i++){
				ofEllipse(ofGetMouseX(),
						  ofGetMouseY(),
						  20.0+i*i,
						  20.0+i*i);
			}
		}
	}

	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
}

BasicScreenObject* Renderer::getObjectAt(float _screenx, float _screeny){
	int fbox	=_screenx/mapsampling;
	int fboy	=_screeny/mapsampling;
	fbox		= ofClamp(fbox, 0, maxbounds.width);
	fboy		= ofClamp(fboy, 0, maxbounds.height);

	int index	= (fbox + fboy * pickingmap.getWidth()) * 3 ;
	//int index	= (fbox + fboy * pickingmap.getWidth());

	ofColor	fboc			= ofColor( mapPixels[index] , mapPixels[index + 1] , mapPixels[index + 2] );
	//ofColor	fboc			= ofColor( mapPixels[index] , mapPixels[index] , mapPixels[index] );
	GLint pickingName		= colorToPickingName(fboc);
	BasicScreenObject* obj	= NULL;

	if (pickingObjects.find(pickingName) != pickingObjects.end()) {
		obj = pickingObjects[pickingName];
	}
	return obj;
}

GLuint Renderer::getNextPickingName(BasicInteractiveObject* _object) {
	GLuint np = ++nextPickingName;
	pickingObjects[np] = _object;
	return np;
}

long Renderer::lastInteractionMillis(){
	return lastinteraction;
}

void Renderer::isDrawCursors(bool _drawCursors) {
	drawcursors = _drawCursors;
}

<|endoftext|>


<commit_before>#include "logreader.h"

Logreader::Logreader(QString filename, QString address, quint16 port){
    if (address == "127.0.0.1") {
        this->address = new QHostAddress(QHostAddress::LocalHost);
    } else {
        this->address = new QHostAddress(address);
    }
    this->port = port;
    this->log = new QFile(filename);

    if (this->log->open(QIODevice::ReadOnly)) {
        qDebug() << "File: " << filename << "successfuly opened." << "\n";
    } else {
        qDebug() << "Opening file" << filename << "failed." << "\n";
    }
}

Logreader::Logreader(QString filename, QHostAddress address, quint16 port){
    this->address = &address;
    this->port = port;

    this->log = new QFile(filename);

    if (this->log->open(QIODevice::ReadOnly)) {
        qDebug() << "File: " << filename << "successfuly opened." << "\n";
    } else {
        qDebug() << "Opening file" << filename << "failed." << "\n";
    }
}

QString Logreader::getLine(){
    return this->line;
}

int Logreader::readAndTransmit(){
    QString fileLine;
    QString parsedFileLine;
    fileLine = readDataFromFile();
    parsedFileLine = parseData(fileLine);
    transmitData(parsedFileLine);
    qDebug() << parsedFileLine;
    counter++;
    if (counter==2){
          packetno ++;
          counter = 0;
        }
    if (packetno > 2){
          packetno = 0;
    }
    return 0;
}

QString Logreader::readDataFromFile(){
    QString fileLine;
    if ((log->isReadable()) && (!log->atEnd())){
        fileLine = this->log->readLine();
    } else if (!log->isReadable()) {
        qDebug() << "File " << this->filename << " is not readable.\n";
    } else if (log->atEnd()) {
        log->seek(0);
    }
    return fileLine;
}

QString Logreader::parseData(QString fileLine){
    QList<QString> parsingData;
    QString parsedFileLine;
    QString processData;

    processData.clear();
    parsingData.clear();
    parsedFileLine.clear();

    foreach (QChar var, fileLine) {
        if ((var != ';')&& (var != '\r')){
            processData.append(var);
        } else if ((var == ';')|| (var == '\r')){
            parsingData.append(processData);
            processData.clear();
        }
    }

    // Chain for transmission assembly
    // TODO: Complete the parsed string and include a clause which will change the string to a status once in a while.
    if (!parsingData.isEmpty()) {
        switch (packetno){
        case 0:parsedFileLine.append("$MSG,");
               parsedFileLine.append("LAT");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(0));
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(1));
               parsedFileLine.append(',');
               parsedFileLine.append("LON");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(2));
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(3));
               parsedFileLine.append('*');
               parsedFileLine.append(checksum(parsedFileLine));
               parsedFileLine.append('\r');
               parsedFileLine.append('\n'); break;
        case 1:parsedFileLine.append("$MSG,");
               parsedFileLine.append("VLC");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(5));
               parsedFileLine.append(',');
               parsedFileLine.append("ENG");
               parsedFileLine.append("LS");
               parsedFileLine.append(',');
               parsedFileLine.append("xxx");
               parsedFileLine.append(',');
               parsedFileLine.append("ACX");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(6));
               parsedFileLine.append(',');
               parsedFileLine.append("ACY");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(7));
               parsedFileLine.append(',');
               parsedFileLine.append("ACZ");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(8));
               parsedFileLine.append('*');
               parsedFileLine.append(checksum(parsedFileLine));
               parsedFileLine.append('\r');
               parsedFileLine.append('\n'); break;
        case 2:parsedFileLine.append("$MSG,");
               parsedFileLine.append("HDG");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(4));
               parsedFileLine.append(',');
               parsedFileLine.append("HDT");
               parsedFileLine.append(',');
               parsedFileLine.append("xxx");
               parsedFileLine.append(',');
               parsedFileLine.append("ACP");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(9));
               parsedFileLine.append(',');
               parsedFileLine.append("ACW");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(10));
               parsedFileLine.append(',');
               parsedFileLine.append("ACR");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(11));
               parsedFileLine.append('*');
               parsedFileLine.append(checksum(parsedFileLine));
               parsedFileLine.append('\r');
               parsedFileLine.append('\n'); break;
        default: parsedFileLine.append("error");
        }
    }

    return parsedFileLine;
}

void Logreader::transmitData(QString inString){
    transmitter.writeDatagram(inString.toLatin1(), *this->address, port);
}

QString Logreader::checksum(QByteArray inData){
    QString table = "0123456789ABCDEF";
    char result[2];
    QString outChecksum;

    unsigned char checksum = 0x00;

    for (int i = 1; i < inData.length()-1; i++) {
        if (inData.at(i)=='*') {
            break;
        }
        checksum ^= (unsigned char) inData.at(i);
    }

    result[1] = table.at(checksum&0x0F).toLatin1();
    result[0] = table.at((checksum>>4)&0x0F).toLatin1();
    outChecksum.insert(0,result[0]);
    outChecksum.insert(1,result[1]);
    return outChecksum;
}

QString Logreader::checksum(QString inData){
    return checksum(inData.toLatin1());
}
<commit_msg>added parsing sentence for data with no fake log<commit_after>#include "logreader.h"

Logreader::Logreader(QString filename, QString address, quint16 port){
    if (address == "127.0.0.1") {
        this->address = new QHostAddress(QHostAddress::LocalHost);
    } else {
        this->address = new QHostAddress(address);
    }
    this->port = port;
    this->log = new QFile(filename);

    if (this->log->open(QIODevice::ReadOnly)) {
        qDebug() << "File: " << filename << "successfuly opened." << "\n";
    } else {
        qDebug() << "Opening file" << filename << "failed." << "\n";
    }
}

Logreader::Logreader(QString filename, QHostAddress address, quint16 port){
    this->address = &address;
    this->port = port;

    this->log = new QFile(filename);

    if (this->log->open(QIODevice::ReadOnly)) {
        qDebug() << "File: " << filename << "successfuly opened." << "\n";
    } else {
        qDebug() << "Opening file" << filename << "failed." << "\n";
    }
}

QString Logreader::getLine(){
    return this->line;
}

int Logreader::readAndTransmit(){
    QString fileLine;
    QString parsedFileLine;
    fileLine = readDataFromFile();
    parsedFileLine = parseData(fileLine);
    transmitData(parsedFileLine);
    qDebug() << parsedFileLine;
    counter++;
    if (counter==2){
          packetno ++;
          counter = 0;
        }
    if (packetno > 2){
          packetno = 0;
    }
    return 0;
}

QString Logreader::readDataFromFile(){
    QString fileLine;
    if ((log->isReadable()) && (!log->atEnd())){
        fileLine = this->log->readLine();
    } else if (!log->isReadable()) {
        qDebug() << "File " << this->filename << " is not readable.\n";
    } else if (log->atEnd()) {
        log->seek(0);
    }
    return fileLine;
}

QString Logreader::parseData(QString fileLine){
    QList<QString> parsingData;
    QString parsedFileLine;
    QString processData;

    processData.clear();
    parsingData.clear();
    parsedFileLine.clear();

    foreach (QChar var, fileLine) {
        if ((var != ';')&& (var != '\r')){
            processData.append(var);
        } else if ((var == ';')|| (var == '\r')){
            parsingData.append(processData);
            processData.clear();
        }
    }

    // Chain for transmission assembly
    // TODO: Complete the parsed string and include a clause which will change the string to a status once in a while.
    if (!parsingData.isEmpty()) {
        switch (packetno){
        case 0:parsedFileLine.append("$MSG,");
               parsedFileLine.append("LAT");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(0));
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(1));
               parsedFileLine.append(',');
               parsedFileLine.append("LON");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(2));
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(3));
               /*parsedFileLine.append("LATDG");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(LATDEG));
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(LATMINS));
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(LATSEC));*/
               //code above has no fake log
               parsedFileLine.append('*');
               parsedFileLine.append(checksum(parsedFileLine));
               parsedFileLine.append('\r');
               parsedFileLine.append('\n'); break;
        case 1:parsedFileLine.append("$MSG,");
               parsedFileLine.append("VLC");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(5));
               parsedFileLine.append(',');
               parsedFileLine.append("ENG");
               parsedFileLine.append("LS");
               parsedFileLine.append(',');
               parsedFileLine.append("xxx");
               parsedFileLine.append(',');
               parsedFileLine.append("ACX");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(6));
               parsedFileLine.append(',');
               parsedFileLine.append("ACY");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(7));
               parsedFileLine.append(',');
               parsedFileLine.append("ACZ");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(8));
               parsedFileLine.append('*');
               parsedFileLine.append(checksum(parsedFileLine));
               parsedFileLine.append('\r');
               parsedFileLine.append('\n'); break;
        case 2:parsedFileLine.append("$MSG,");
               parsedFileLine.append("HDG");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(4));
               parsedFileLine.append(',');
               parsedFileLine.append("HDT");
               parsedFileLine.append(',');
               parsedFileLine.append("xxx");
               parsedFileLine.append(',');
               parsedFileLine.append("ACP");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(9));
               parsedFileLine.append(',');
               parsedFileLine.append("ACW");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(10));
               parsedFileLine.append(',');
               parsedFileLine.append("ACR");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(11));
               parsedFileLine.append('*');
               parsedFileLine.append(checksum(parsedFileLine));
               parsedFileLine.append('\r');
               parsedFileLine.append('\n'); break;
        /*case 3:parsedFileLine.append("$MSG,");
               parsedFileLine.append("LDR");
               parsedFileLine.append(',');
               for (int i = 1; i<17;i++){
                   parsedFileLine.append(parsingData.at(i));
               }
               parsedFileLine.append("HP");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(PHDG));
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(PHPTH));
               parsedFileLine.append(',');
               parsedFileLine.append("HPF");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(FREQ));
               parsedFileLine.append('*');
               parsedFileLine.append(checksum(parsedFileLine));
               parsedFileLine.append('\r');
               parsedFileLine.append('\n'); break;
        case 4:parsedFileLine.append("$MSG,");
               parsedFileLine.append("GPS");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(1/0));
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(1/0)));
               parsedFileLine.append(',');
               parsedFileLine.append("IMU");
               parsedFileLine.append(',');
               parsedFileLine.append(parsingData.at(1/0)));
               parsedFileLine.append('*');
               parsedFileLine.append(checksum(parsedFileLine));
               parsedFileLine.append('\r');
               parsedFileLine.append('\n'); break;*/
               //NO FAKE LOG

        default: parsedFileLine.append("error");
        }
    }

    return parsedFileLine;
}

void Logreader::transmitData(QString inString){
    transmitter.writeDatagram(inString.toLatin1(), *this->address, port);
}

QString Logreader::checksum(QByteArray inData){
    QString table = "0123456789ABCDEF";
    char result[2];
    QString outChecksum;

    unsigned char checksum = 0x00;

    for (int i = 1; i < inData.length()-1; i++) {
        if (inData.at(i)=='*') {
            break;
        }
        checksum ^= (unsigned char) inData.at(i);
    }

    result[1] = table.at(checksum&0x0F).toLatin1();
    result[0] = table.at((checksum>>4)&0x0F).toLatin1();
    outChecksum.insert(0,result[0]);
    outChecksum.insert(1,result[1]);
    return outChecksum;
}

QString Logreader::checksum(QString inData){
    return checksum(inData.toLatin1());
}
<|endoftext|>