<commit_before>// Copyright ***********************************************************
//
// File ecmdCommandUtils.C
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 1996
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright *******************************************************
/* $Header$ */

// Module Description **************************************************
//
// Description:
//
// End Module Description **********************************************

//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define ecmdCommandUtils_C
#include <list>
#include <fstream>
#include <inttypes.h>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include <ecmdCommandUtils.H>
#include <ecmdReturnCodes.H>
#include <ecmdClientCapi.H>
#undef ecmdCommandUtils_C
//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//---------------------------------------------------------------------
// Member Function Specifications
//---------------------------------------------------------------------

uint32_t ecmdCheckExpected (ecmdDataBuffer & i_data, ecmdDataBuffer & i_expected) {

  int wordCounter = 0;
  uint32_t maxBits = 32;
  uint32_t numBits = i_data.getBitLength();
  uint32_t numToFetch = numBits < maxBits ? numBits : maxBits;
  uint32_t curData, curExpected;

  /* We are going to make sure they didn't expect more data then we had */
  /* We are going to allow for odd bits in a nibble if the user provided data in hex */
  /* We will just check below that all the extra data was zero's */
  if ((i_data.getBitLength()-1)/4 > (i_expected.getBitLength()-1)/4) {
    ecmdOutputError("ecmdCheckExpected - Not enough expect data provided\n");
    return 0;
  } else if ((i_data.getBitLength()-1)/4 < (i_expected.getBitLength()-1)/4) {
    ecmdOutputError("ecmdCheckExpected - More expect data provided than data that was retrieved\n");
    return 0;

    /* Now we are going to check to see if expect bits we specified in any odd nibble bits */
  } else if ((i_data.getBitLength() < i_expected.getBitLength()) &&
             (!i_expected.isBitClear(i_data.getBitLength(), i_expected.getBitLength() - i_data.getBitLength()))) {
    ecmdOutputError("ecmdCheckExpected - More non-zero expect data provided in odd bits of a nibble then data retrieved\n");
    return 0;
  }

  while (numToFetch > 0) {

    curData = i_data.getWord(wordCounter);
    curExpected = i_expected.getWord(wordCounter);

    if (numToFetch == maxBits) {
      if (curData != curExpected)
        return 0;
    }
    else {
      uint32_t mask = 0x80000000;
      for (int i = 0; i < numToFetch; i++, mask >>= 1) {
        if ( (curData & mask) != (curExpected & mask) ) {
          return 0;
        }
      }
    }

    numBits -= numToFetch;
    numToFetch = (numBits < maxBits) ? numBits : maxBits;
    wordCounter++;
  }

  return 1;

}

uint32_t ecmdApplyDataModifier (ecmdDataBuffer & io_data, ecmdDataBuffer & i_newData, int i_startbit, std::string i_modifier) {
  uint32_t rc = ECMD_SUCCESS;

  if ((i_startbit + i_newData.getBitLength()) > io_data.getBitLength()) {
    char buf[200];
    sprintf(buf,"ecmdApplyDataModifier - startbit + numbits (%d) > data length (%d), buffer overflow!\n",i_startbit + i_newData.getBitLength(), io_data.getBitLength());
    ecmdOutputError(buf);
    return ECMD_INVALID_ARGS;
  }

  if (i_modifier == "insert") {
    io_data.insert(i_newData, i_startbit, i_newData.getBitLength());
  } else if (i_modifier == "and") {
    io_data.setAnd(i_newData, i_startbit, i_newData.getBitLength());
  } else if (i_modifier == "or") {
    io_data.setOr(i_newData, i_startbit, i_newData.getBitLength());
  } else {
    ecmdOutputError(("ecmdApplyDataModifier - Invalid Data Modifier specified with -b arg : "+i_modifier + "\n").c_str());
    return ECMD_INVALID_ARGS;
  }

  return rc;
}

uint32_t ecmdPrintHelp(const char* i_command) {

  uint32_t rc = ECMD_SUCCESS;
  std::string file;
  ecmdChipTarget target;
  std::ifstream ins;
  std::string curLine;

  /* Get the path to the help text files */
  rc = ecmdQueryFileLocation(target, ECMD_FILE_HELPTEXT, file);
  if (rc) return rc;

  file += i_command; file += ".htxt";

  /* Let's go open this guy */
  ins.open(file.c_str());
  if (ins.fail()) {
    ecmdOutputError(("Error occured opening help text file: " + file + "\n").c_str());
    return ECMD_INVALID_ARGS;  //change this
  }

  while (getline(ins, curLine)) {
    curLine += '\n';
    ecmdOutput(curLine.c_str());
  }
  ins.close();

  return rc;

}

uint32_t ecmdGenB32FromHex (uint32_t * o_numPtr, const char * i_hexChars, int startPos) {

  uint32_t tempB32 = 0;
  int	counter = 0;
  char	twoChars[2] = "0";

  if ((o_numPtr == NULL) || (i_hexChars == NULL) || (strlen(i_hexChars) == 0))
    return 0xFFFFFFFF;

  o_numPtr[0] = 0x0;
  o_numPtr[startPos>>3]= 0x0;

  for (counter = 0; counter < strlen(i_hexChars); counter++) {
    if (((counter + startPos) & 0xFFF8) == (counter + startPos))
      o_numPtr[(counter+startPos)>>3] = 0x0;
    twoChars[0] = i_hexChars[counter];
    tempB32 = strtoul((char *) & twoChars[0], NULL, 16);
    o_numPtr[(counter+startPos)>>3] |= (tempB32 << (28 - (4 * ((counter + startPos) & 0x07))));
  }

  return o_numPtr[0];

}

uint32_t ecmdGenB32FromHexLeft (uint32_t * o_numPtr, const char * i_hexChars) {

  if ((i_hexChars == NULL) || (o_numPtr == NULL))
    return 0xFFFFFFFF;

  return ecmdGenB32FromHex(o_numPtr, i_hexChars, 0);

}

uint32_t ecmdGenB32FromHexRight (uint32_t * o_numPtr, const char * i_hexChars, int expectBits) {

  int stringSize;

  if ((i_hexChars == NULL) || (o_numPtr == NULL))
    return 0xFFFFFFFF;

  /* ----------------------------------------------------------------- */
  /* Telling us we are expecting few bits than the user input          */
  /* ----------------------------------------------------------------- */
  stringSize = strlen(i_hexChars);

  if (expectBits==0)
    expectBits = ((stringSize << 2) + 31) & 0xFFFE0;

  /* ----------------------------------------------------------------- */
  /* Can't figure out if this case is bad...                           */
  /* ----------------------------------------------------------------- */
  if (expectBits<(stringSize*4))
    expectBits = (4-(expectBits & 0x3))+expectBits+(stringSize*4-expectBits&0xFFFC);

  expectBits = (expectBits - stringSize*4)>>2;

  return ecmdGenB32FromHex(o_numPtr, i_hexChars, expectBits );

}

/* Returns true if all chars of str are decimal numbers */
bool ecmdIsAllDecimal(const char* str) {

  bool ret = true;
  int len = strlen(str);
  for (int x = 0; x < len; x ++) {
    if (!isdigit(str[x])) {
      ret = false;
      break;
    }
  }

  return ret;
}

/* Returns true if all chars of str are hex numbers */
bool ecmdIsAllHex(const char* str) {

  bool ret = true;
  int len = strlen(str);
  for (int x = 0; x < len; x ++) {
    if (!isxdigit(str[x])) {
      ret = false;
      break;
    }
  }

  return ret;
}

std::string ecmdParseReturnCode(uint32_t i_returnCode) {
  std::string ret;

  ecmdChipTarget dummy;
  std::string filePath;
  uint32_t rc = ecmdQueryFileLocation(dummy, ECMD_FILE_HELPTEXT, filePath);

  if (rc || (filePath.length()==0)) {
    ret = "ERROR FINDING DECODE FILE";
    return ret;
  }

  filePath += "ecmdReturnCodes.H";

  /* jtw 10/6/03 - code below largely copied from cronusrc.c */
  char str[800];
  char num[30];
  char name[200];
  int found = 0;
  char* tempstr = NULL;
  unsigned int comprc;

  std::ifstream ins(filePath.c_str());

  if (ins.fail()) {
    ret = "ERROR OPENING DECODE FILE";
    return ret;
  }

  while (!ins.eof()) { /*  && (strlen(str) != 0) */
    ins.getline(str,799,'\n');
    if (!strncmp(str,"#define",7)) {
      strtok(str," \t");        /* get rid of the #define */
      tempstr = strtok(NULL," \t");
      if (tempstr == NULL) continue;
      strcpy(name,tempstr);
      tempstr = strtok(NULL," \t");
      if (tempstr == NULL) continue;
      strcpy(num,tempstr);
      sscanf(num,"%x",&comprc);
      if (comprc == i_returnCode) {
        ret = name;
        found = 1;
        break;
      }
    }
  }

  ins.close();

  if (!found) {
    ret = "UNDEFINED";
  }
  return ret;
}

// Change Log *********************************************************
//
//  Flag Reason   Vers Date     Coder    Description
//  ---- -------- ---- -------- -------- ------------------------------
//                              CENGEL   Initial Creation
//
// End Change Log *****************************************************
<commit_msg>Updates to return code parsing for BZ#219<commit_after>// Copyright ***********************************************************
//
// File ecmdCommandUtils.C
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 1996
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright *******************************************************
/* $Header$ */

// Module Description **************************************************
//
// Description:
//
// End Module Description **********************************************

//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define ecmdCommandUtils_C
#include <list>
#include <fstream>
#include <inttypes.h>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include <ecmdCommandUtils.H>
#include <ecmdReturnCodes.H>
#include <ecmdClientCapi.H>
#include <ecmdSharedUtils.H>

#undef ecmdCommandUtils_C
//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//---------------------------------------------------------------------
// Member Function Specifications
//---------------------------------------------------------------------

uint32_t ecmdCheckExpected (ecmdDataBuffer & i_data, ecmdDataBuffer & i_expected) {

  int wordCounter = 0;
  uint32_t maxBits = 32;
  uint32_t numBits = i_data.getBitLength();
  uint32_t numToFetch = numBits < maxBits ? numBits : maxBits;
  uint32_t curData, curExpected;

  /* We are going to make sure they didn't expect more data then we had */
  /* We are going to allow for odd bits in a nibble if the user provided data in hex */
  /* We will just check below that all the extra data was zero's */
  if ((i_data.getBitLength()-1)/4 > (i_expected.getBitLength()-1)/4) {
    ecmdOutputError("ecmdCheckExpected - Not enough expect data provided\n");
    return 0;
  } else if ((i_data.getBitLength()-1)/4 < (i_expected.getBitLength()-1)/4) {
    ecmdOutputError("ecmdCheckExpected - More expect data provided than data that was retrieved\n");
    return 0;

    /* Now we are going to check to see if expect bits we specified in any odd nibble bits */
  } else if ((i_data.getBitLength() < i_expected.getBitLength()) &&
             (!i_expected.isBitClear(i_data.getBitLength(), i_expected.getBitLength() - i_data.getBitLength()))) {
    ecmdOutputError("ecmdCheckExpected - More non-zero expect data provided in odd bits of a nibble then data retrieved\n");
    return 0;
  }

  while (numToFetch > 0) {

    curData = i_data.getWord(wordCounter);
    curExpected = i_expected.getWord(wordCounter);

    if (numToFetch == maxBits) {
      if (curData != curExpected)
        return 0;
    }
    else {
      uint32_t mask = 0x80000000;
      for (int i = 0; i < numToFetch; i++, mask >>= 1) {
        if ( (curData & mask) != (curExpected & mask) ) {
          return 0;
        }
      }
    }

    numBits -= numToFetch;
    numToFetch = (numBits < maxBits) ? numBits : maxBits;
    wordCounter++;
  }

  return 1;

}

uint32_t ecmdApplyDataModifier (ecmdDataBuffer & io_data, ecmdDataBuffer & i_newData, int i_startbit, std::string i_modifier) {
  uint32_t rc = ECMD_SUCCESS;

  if ((i_startbit + i_newData.getBitLength()) > io_data.getBitLength()) {
    char buf[200];
    sprintf(buf,"ecmdApplyDataModifier - startbit + numbits (%d) > data length (%d), buffer overflow!\n",i_startbit + i_newData.getBitLength(), io_data.getBitLength());
    ecmdOutputError(buf);
    return ECMD_INVALID_ARGS;
  }

  if (i_modifier == "insert") {
    io_data.insert(i_newData, i_startbit, i_newData.getBitLength());
  } else if (i_modifier == "and") {
    io_data.setAnd(i_newData, i_startbit, i_newData.getBitLength());
  } else if (i_modifier == "or") {
    io_data.setOr(i_newData, i_startbit, i_newData.getBitLength());
  } else {
    ecmdOutputError(("ecmdApplyDataModifier - Invalid Data Modifier specified with -b arg : "+i_modifier + "\n").c_str());
    return ECMD_INVALID_ARGS;
  }

  return rc;
}

uint32_t ecmdPrintHelp(const char* i_command) {

  uint32_t rc = ECMD_SUCCESS;
  std::string file;
  ecmdChipTarget target;
  std::ifstream ins;
  std::string curLine;

  /* Get the path to the help text files */
  rc = ecmdQueryFileLocation(target, ECMD_FILE_HELPTEXT, file);
  if (rc) return rc;

  file += i_command; file += ".htxt";

  /* Let's go open this guy */
  ins.open(file.c_str());
  if (ins.fail()) {
    ecmdOutputError(("Error occured opening help text file: " + file + "\n").c_str());
    return ECMD_INVALID_ARGS;  //change this
  }

  while (getline(ins, curLine)) {
    curLine += '\n';
    ecmdOutput(curLine.c_str());
  }
  ins.close();

  return rc;

}

uint32_t ecmdGenB32FromHex (uint32_t * o_numPtr, const char * i_hexChars, int startPos) {

  uint32_t tempB32 = 0;
  int	counter = 0;
  char	twoChars[2] = "0";

  if ((o_numPtr == NULL) || (i_hexChars == NULL) || (strlen(i_hexChars) == 0))
    return 0xFFFFFFFF;

  o_numPtr[0] = 0x0;
  o_numPtr[startPos>>3]= 0x0;

  for (counter = 0; counter < strlen(i_hexChars); counter++) {
    if (((counter + startPos) & 0xFFF8) == (counter + startPos))
      o_numPtr[(counter+startPos)>>3] = 0x0;
    twoChars[0] = i_hexChars[counter];
    tempB32 = strtoul((char *) & twoChars[0], NULL, 16);
    o_numPtr[(counter+startPos)>>3] |= (tempB32 << (28 - (4 * ((counter + startPos) & 0x07))));
  }

  return o_numPtr[0];

}

uint32_t ecmdGenB32FromHexLeft (uint32_t * o_numPtr, const char * i_hexChars) {

  if ((i_hexChars == NULL) || (o_numPtr == NULL))
    return 0xFFFFFFFF;

  return ecmdGenB32FromHex(o_numPtr, i_hexChars, 0);

}

uint32_t ecmdGenB32FromHexRight (uint32_t * o_numPtr, const char * i_hexChars, int expectBits) {

  int stringSize;

  if ((i_hexChars == NULL) || (o_numPtr == NULL))
    return 0xFFFFFFFF;

  /* ----------------------------------------------------------------- */
  /* Telling us we are expecting few bits than the user input          */
  /* ----------------------------------------------------------------- */
  stringSize = strlen(i_hexChars);

  if (expectBits==0)
    expectBits = ((stringSize << 2) + 31) & 0xFFFE0;

  /* ----------------------------------------------------------------- */
  /* Can't figure out if this case is bad...                           */
  /* ----------------------------------------------------------------- */
  if (expectBits<(stringSize*4))
    expectBits = (4-(expectBits & 0x3))+expectBits+(stringSize*4-expectBits&0xFFFC);

  expectBits = (expectBits - stringSize*4)>>2;

  return ecmdGenB32FromHex(o_numPtr, i_hexChars, expectBits );

}

/* Returns true if all chars of str are decimal numbers */
bool ecmdIsAllDecimal(const char* str) {

  bool ret = true;
  int len = strlen(str);
  for (int x = 0; x < len; x ++) {
    if (!isdigit(str[x])) {
      ret = false;
      break;
    }
  }

  return ret;
}

/* Returns true if all chars of str are hex numbers */
bool ecmdIsAllHex(const char* str) {

  bool ret = true;
  int len = strlen(str);
  for (int x = 0; x < len; x ++) {
    if (!isxdigit(str[x])) {
      ret = false;
      break;
    }
  }

  return ret;
}

std::string ecmdParseReturnCode(uint32_t i_returnCode) {
  std::string ret = "";

  ecmdChipTarget dummy;
  std::string filePath;
  uint32_t rc = ecmdQueryFileLocation(dummy, ECMD_FILE_HELPTEXT, filePath);

  if (rc || (filePath.length()==0)) {
    ret = "ERROR FINDING DECODE FILE";
    return ret;
  }

  filePath += "ecmdReturnCodes.H";

  std::string line;
  std::vector< std::string > tokens;
  std::string source, retdefine;
  int found = 0;
  uint32_t comprc;

  std::ifstream ins(filePath.c_str());

  if (ins.fail()) {
    ret = "ERROR OPENING DECODE FILE";
    return ret;
  }

  /* This is what I am trying to parse from ecmdReturnCodes.H */

  /* #define ECMD_ERR_UNKNOWN                        0x00000000 ///< This error code wasn't flagged to which plugin it came from        */
  /* #define ECMD_ERR_ECMD                           0x01000000 ///< Error came from eCMD                                               */
  /* #define ECMD_ERR_CRONUS                         0x02000000 ///< Error came from Cronus                                             */
  /* #define ECMD_ERR_IP                             0x04000000 ///< Error came from IP GFW                                             */
  /* #define ECMD_ERR_Z                              0x08000000 ///< Error came from Z GFW                                              */
  /* #define ECMD_INVALID_DLL_VERSION                (ECMD_ERR_ECMD | 0x1000) ///< Dll Version                                          */

  while (!ins.eof()) { /*  && (strlen(str) != 0) */
    getline(ins,line,'\n');
    /* Let's strip off any comments */
    line = line.substr(0, line.find_first_of("/"));
    ecmdParseTokens(line, " \n()|", tokens);

    /* Didn't find anything */
    if (line.size() < 2) continue;

    if (tokens[0] == "#define") {
      /* Let's see if we have one of they return code source defines */
      if ((tokens.size() == 3) && (tokens[1] != "ECMD_SUCCESS") && (tokens[1] != "ECMD_DBUF_SUCCESS")) {
        sscanf(tokens[2].c_str(),"0x%x",&comprc);
        if ((i_returnCode & 0xFF000000) == comprc) {
          /* This came from this source, we will save that as we may use it later */
          source = tokens[1];
        }
      } else if (i_returnCode & 0xFF000000 != ECMD_ERR_ECMD) {
        /* We aren't going to find this return code in here since it didn't come from us */
      } else if (tokens.size() == 4) {
        /* This is a standard return code define */
        sscanf(tokens[3].c_str(),"0x%x",&comprc);
        if ((i_returnCode & 0x00FFFFFF) == comprc) {
          /* This came from this source, we will save that as we may use it later */
          retdefine = tokens[1];
          found = 1;
          break;
        }
      }
    }
  }

  ins.close();

  if (!found && source.length() == 0) {
    ret = "UNDEFINED";
  } else if (!found) {
    ret = "UNDEFINED FROM " + source;
  } else {
    ret = retdefine;
  }
  return ret;
}

// Change Log *********************************************************
//
//  Flag Reason   Vers Date     Coder    Description
//  ---- -------- ---- -------- -------- ------------------------------
//                              CENGEL   Initial Creation
//
// End Change Log *****************************************************
<|endoftext|>


<commit_before>/// \file
/// \ingroup tutorial_eve
/// Demonstates usage of geometry aliases - merge ALICE ITS with ATLAS MUON.
///
/// \image html eve_geom_alias.png
/// \macro_code
///
/// \author Matevz Tadel

void geom_alias()
{
   TEveManager::Create();

   gEve->RegisterGeometryAlias("ALICE", "http://root.cern.ch/files/alice.root");
   gEve->RegisterGeometryAlias("ATLAS", "http://root.cern.ch/files/atlas.root");

   gGeoManager = gEve->GetGeometryByAlias("ALICE");

   TGeoNode* node1 = gGeoManager->GetTopVolume()->FindNode("ITSV_1");
   TEveGeoTopNode* its = new TEveGeoTopNode(gGeoManager, node1);
   gEve->AddGlobalElement(its);

   gGeoManager = gEve->GetGeometryByAlias("ATLAS");

   TGeoNode* node2 = gGeoManager->GetTopVolume()->FindNode("OUTE_1");
   TEveGeoTopNode* atlas = new TEveGeoTopNode(gGeoManager, node2);
   gEve->AddGlobalElement(atlas);

   gEve->FullRedraw3D(kTRUE);

   // EClipType not exported to CINT (see TGLUtil.h):
   // 0 - no clip, 1 - clip plane, 2 - clip box
   TGLViewer *v = gEve->GetDefaultGLViewer();
   v->GetClipSet()->SetClipType(TGLClip::EType(2));
   v->RefreshPadEditor(v);

   v->CurrentCamera().RotateRad(-0.5, -2.4);
   v->DoDraw();
}
<commit_msg>- spell check - use auto<commit_after>/// \file
/// \ingroup tutorial_eve
/// Demonstrates usage of geometry aliases - merge ALICE ITS with ATLAS MUON.
///
/// \image html eve_geom_alias.png
/// \macro_code
///
/// \author Matevz Tadel

void geom_alias()
{
   TEveManager::Create();

   gEve->RegisterGeometryAlias("ALICE", "http://root.cern.ch/files/alice.root");
   gEve->RegisterGeometryAlias("ATLAS", "http://root.cern.ch/files/atlas.root");

   gGeoManager = gEve->GetGeometryByAlias("ALICE");

   auto node1 = gGeoManager->GetTopVolume()->FindNode("ITSV_1");
   auto its   = new TEveGeoTopNode(gGeoManager, node1);
   gEve->AddGlobalElement(its);

   gGeoManager = gEve->GetGeometryByAlias("ATLAS");

   auto node2 = gGeoManager->GetTopVolume()->FindNode("OUTE_1");
   auto atlas = new TEveGeoTopNode(gGeoManager, node2);
   gEve->AddGlobalElement(atlas);

   gEve->FullRedraw3D(kTRUE);

   // EClipType not exported to CINT (see TGLUtil.h):
   // 0 - no clip, 1 - clip plane, 2 - clip box
   auto v = gEve->GetDefaultGLViewer();
   v->GetClipSet()->SetClipType(TGLClip::EType(2));
   v->RefreshPadEditor(v);

   v->CurrentCamera().RotateRad(-0.5, -2.4);
   v->DoDraw();
}
<|endoftext|>


<commit_before>/// \file
/// \ingroup tutorial_graphics
/// \notebook
/// This tutorial illustrates the special contour options.
///
///   - "AITOFF"     : Draw a contour via an AITOFF projection
///   - "MERCATOR"   : Draw a contour via an Mercator projection
///   - "SINUSOIDAL" : Draw a contour via an Sinusoidal projection
///   - "PARABOLIC"  : Draw a contour via an Parabolic projection
///
/// \macro_image
/// \macro_code
///
/// \author Olivier Couet (from an original macro sent by Ernst-Jan Buis)

void earth(){

   gStyle->SetOptTitle(1);
   gStyle->SetOptStat(0);

   auto c1 = new TCanvas("c1","earth_projections",700,700);
   c1->Divide(2,2);

   auto ha = new TH2F("ha","Aitoff",    180, -180, 180, 179, -89.5, 89.5);
   auto hm = new TH2F("hm","Mercator",  180, -180, 180, 161, -80.5, 80.5);
   auto hs = new TH2F("hs","Sinusoidal",180, -180, 180, 181, -90.5, 90.5);
   auto hp = new TH2F("hp","Parabolic", 180, -180, 180, 181, -90.5, 90.5);

   TString dat = gROOT->GetTutorialDir();
   dat.Append("/graphics/earth.dat");
   dat.ReplaceAll("/./","/");

   ifstream in;
   in.open(dat.Data());
   Float_t x,y;
   while (1) {
     in >> x >> y;
     if (!in.good()) break;
     ha->Fill(x,y, 1);
     hm->Fill(x,y, 1);
     hs->Fill(x,y, 1);
     hp->Fill(x,y, 1);
   }
   in.close();

   c1->cd(1); ha->Draw("aitoff");
   c1->cd(2); hm->Draw("mercator");
   c1->cd(3); hs->Draw("sinusoidal");
   c1->cd(4); hp->Draw("parabolic");
}
<commit_msg>Revert "Modernise and simplify example"<commit_after>/// \file
/// \ingroup tutorial_graphics
/// \notebook
/// This tutorial illustrates the special contour options.
///
///   - "AITOFF"     : Draw a contour via an AITOFF projection
///   - "MERCATOR"   : Draw a contour via an Mercator projection
///   - "SINUSOIDAL" : Draw a contour via an Sinusoidal projection
///   - "PARABOLIC"  : Draw a contour via an Parabolic projection
///
/// \macro_image
/// \macro_code
///
/// \author Olivier Couet (from an original macro sent by Ernst-Jan Buis)

TCanvas *earth(){

   gStyle->SetOptTitle(1);
   gStyle->SetOptStat(0);

   TCanvas *c1 = new TCanvas("c1","earth_projections",700,700);
   c1->Divide(2,2);

   TH2F *ha = new TH2F("ha","Aitoff",    180, -180, 180, 179, -89.5, 89.5);
   TH2F *hm = new TH2F("hm","Mercator",  180, -180, 180, 161, -80.5, 80.5);
   TH2F *hs = new TH2F("hs","Sinusoidal",180, -180, 180, 181, -90.5, 90.5);
   TH2F *hp = new TH2F("hp","Parabolic", 180, -180, 180, 181, -90.5, 90.5);

   TString dat = gROOT->GetTutorialDir();
   dat.Append("/graphics/earth.dat");
   dat.ReplaceAll("/./","/");

   ifstream in;
   in.open(dat.Data());
   Float_t x,y;
   while (1) {
     in >> x >> y;
     if (!in.good()) break;
     ha->Fill(x,y, 1);
     hm->Fill(x,y, 1);
     hs->Fill(x,y, 1);
     hp->Fill(x,y, 1);
   }
   in.close();

   c1->cd(1); ha->Draw("aitoff");
   c1->cd(2); hm->Draw("mercator");
   c1->cd(3); hs->Draw("sinusoidal");
   c1->cd(4); hp->Draw("parabolic");

   return c1;
}
<|endoftext|>


<commit_before>// pythia8 basic example
//Author: Andreas Morsch
//
// to run, do
//  root > .x pythia8.C
//
// Note that before executing this script,
//   -the env variable PYTHIA8 must point to the pythia8100 (or newer) directory
//   -the env variable PYTHIA8DATA must be defined and it must point to $PYTHIA8/xmldoc
//
void pythia8(Int_t nev  = 100, Int_t ndeb = 1)
{
   char *p8dataenv = gSystem->Getenv("PYTHIA8DATA");
   if (!p8dataenv) {
      char *p8env = gSystem->Getenv("PYTHIA8");
      if (!p8env) {
         Error("pythia8.C",
               "Environment variable PYTHIA8 must contain path to pythia directory!");
         return;
      }
      TString p8d = p8env;
      p8d += "/xmldoc";
      gSystem->Setenv("PYTHIA8DATA", p8d);
   }

   char* path = gSystem->ExpandPathName("$PYTHIA8DATA");
   if (gSystem->AccessPathName(path)) {
         Error("pythia8.C",
               "Environment variable PYTHIA8DATA must contain path to $PYTHIA8/xmldoc directory !");
      return;
   }

// Load libraries
   gSystem->Load("$PYTHIA8/lib/libpythia8");
   gSystem->Load("libEG");
   gSystem->Load("libEGPythia8");
// Histograms
   TH1F* etaH = new TH1F("etaH", "Pseudorapidity", 120, -12., 12.);
   TH1F* ptH  = new TH1F("ptH",  "pt",              50,   0., 10.);

// Array of particles
   TClonesArray* particles = new TClonesArray("TParticle", 1000);
// Create pythia8 object
   TPythia8* pythia8 = new TPythia8();

// Configure
   pythia8->ReadString("SoftQCD:minBias = on");
   pythia8->ReadString("SoftQCD:singleDiffractive = on");
   pythia8->ReadString("SoftQCD:doubleDiffractive = on");

// Initialize

   pythia8->Initialize(2212 /* p */, 2212 /* p */, 14000. /* TeV */);

// Event loop
   for (Int_t iev = 0; iev < nev; iev++) {
      pythia8->GenerateEvent();
      if (iev < ndeb) pythia8->EventListing();
      pythia8->ImportParticles(particles,"All");
      Int_t np = particles->GetEntriesFast();
// Particle loop
      for (Int_t ip = 0; ip < np; ip++) {
         TParticle* part = (TParticle*) particles->At(ip);
         Int_t ist = part->GetStatusCode();
         // Positive codes are final particles.
         if (ist <= 0) continue;
         Int_t pdg = part->GetPdgCode();
         Float_t charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
         if (charge == 0.) continue;
         Float_t eta = part->Eta();
         Float_t pt  = part->Pt();

         etaH->Fill(eta);
         if (pt > 0.) ptH->Fill(pt, 1./(2. * pt));
      }
   }

   pythia8->PrintStatistics();

   TCanvas* c1 = new TCanvas("c1","Pythia8 test example",800,800);
   c1->Divide(1, 2);
   c1->cd(1);
   etaH->Scale(5./Float_t(nev));
   etaH->Draw();
   etaH->SetXTitle("#eta");
   etaH->SetYTitle("dN/d#eta");

   c1->cd(2);
   gPad->SetLogy();
   ptH->Scale(5./Float_t(nev));
   ptH->Draw();
   ptH->SetXTitle("p_{t} [GeV/c]");
   ptH->SetYTitle("dN/dp_{t}^{2} [GeV/c]^{-2}");
 }
<commit_msg>Since Pythia8 is a static library on Windows, don't call gSystem->Load("$PYTHIA8/lib/libpythia8")<commit_after>// pythia8 basic example
//Author: Andreas Morsch
//
// to run, do
//  root > .x pythia8.C
//
// Note that before executing this script,
//   -the env variable PYTHIA8 must point to the pythia8100 (or newer) directory
//   -the env variable PYTHIA8DATA must be defined and it must point to $PYTHIA8/xmldoc
//
void pythia8(Int_t nev  = 100, Int_t ndeb = 1)
{
   char *p8dataenv = gSystem->Getenv("PYTHIA8DATA");
   if (!p8dataenv) {
      char *p8env = gSystem->Getenv("PYTHIA8");
      if (!p8env) {
         Error("pythia8.C",
               "Environment variable PYTHIA8 must contain path to pythia directory!");
         return;
      }
      TString p8d = p8env;
      p8d += "/xmldoc";
      gSystem->Setenv("PYTHIA8DATA", p8d);
   }

   char* path = gSystem->ExpandPathName("$PYTHIA8DATA");
   if (gSystem->AccessPathName(path)) {
         Error("pythia8.C",
               "Environment variable PYTHIA8DATA must contain path to $PYTHIA8/xmldoc directory !");
      return;
   }

// Load libraries
#ifndef G__WIN32 // Pythia8 is a static library on Windows
   gSystem->Load("$PYTHIA8/lib/libpythia8");
#endif
   gSystem->Load("libEG");
   gSystem->Load("libEGPythia8");
// Histograms
   TH1F* etaH = new TH1F("etaH", "Pseudorapidity", 120, -12., 12.);
   TH1F* ptH  = new TH1F("ptH",  "pt",              50,   0., 10.);

// Array of particles
   TClonesArray* particles = new TClonesArray("TParticle", 1000);
// Create pythia8 object
   TPythia8* pythia8 = new TPythia8();

// Configure
   pythia8->ReadString("SoftQCD:minBias = on");
   pythia8->ReadString("SoftQCD:singleDiffractive = on");
   pythia8->ReadString("SoftQCD:doubleDiffractive = on");

// Initialize

   pythia8->Initialize(2212 /* p */, 2212 /* p */, 14000. /* TeV */);

// Event loop
   for (Int_t iev = 0; iev < nev; iev++) {
      pythia8->GenerateEvent();
      if (iev < ndeb) pythia8->EventListing();
      pythia8->ImportParticles(particles,"All");
      Int_t np = particles->GetEntriesFast();
// Particle loop
      for (Int_t ip = 0; ip < np; ip++) {
         TParticle* part = (TParticle*) particles->At(ip);
         Int_t ist = part->GetStatusCode();
         // Positive codes are final particles.
         if (ist <= 0) continue;
         Int_t pdg = part->GetPdgCode();
         Float_t charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
         if (charge == 0.) continue;
         Float_t eta = part->Eta();
         Float_t pt  = part->Pt();

         etaH->Fill(eta);
         if (pt > 0.) ptH->Fill(pt, 1./(2. * pt));
      }
   }

   pythia8->PrintStatistics();

   TCanvas* c1 = new TCanvas("c1","Pythia8 test example",800,800);
   c1->Divide(1, 2);
   c1->cd(1);
   etaH->Scale(5./Float_t(nev));
   etaH->Draw();
   etaH->SetXTitle("#eta");
   etaH->SetYTitle("dN/d#eta");

   c1->cd(2);
   gPad->SetLogy();
   ptH->Scale(5./Float_t(nev));
   ptH->Draw();
   ptH->SetXTitle("p_{t} [GeV/c]");
   ptH->SetYTitle("dN/dp_{t}^{2} [GeV/c]^{-2}");
 }
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.7  2000/04/06 19:09:51  roddey
 * Some more improvements to output formatting. Now it will correctly
 * handle doing the 'replacement char' style of dealing with chars
 * that are unrepresentable.
 *
 * Revision 1.6  2000/04/05 00:20:32  roddey
 * More updates for the low level formatted output support
 *
 * Revision 1.5  2000/03/28 19:43:11  roddey
 * Fixes for signed/unsigned warnings. New work for two way transcoding
 * stuff.
 *
 * Revision 1.4  2000/03/02 19:53:49  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.3  2000/02/11 03:05:35  abagchi
 * Removed second parameter from call to StrX constructor
 *
 * Revision 1.2  2000/02/06 07:47:24  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1.1.1  1999/11/09 01:09:29  twl
 * Initial checkin
 *
 * Revision 1.11  1999/11/08 20:43:42  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/XMLUni.hpp>
#include <sax/AttributeList.hpp>
#include "SAXPrint.hpp"

// ---------------------------------------------------------------------------
//  Local const data
//
//  Note: This is the 'safe' way to do these strings. If you compiler supports
//        L"" style strings, and portability is not a concern, you can use
//        those types constants directly.
// ---------------------------------------------------------------------------
static const XMLCh  gEndElement[] = { chOpenAngle, chForwardSlash, chNull };
static const XMLCh  gEndPI[] = { chQuestion, chCloseAngle, chSpace };
static const XMLCh  gStartPI[] = { chOpenAngle, chQuestion, chSpace };
static const XMLCh  gXMLDecl1[] =
{
        chOpenAngle, chQuestion, chLatin_x, chLatin_m, chLatin_l
    ,   chSpace, chLatin_v, chLatin_e, chLatin_r, chLatin_s, chLatin_i
    ,   chLatin_o, chLatin_n, chEqual, chDoubleQuote, chDigit_1, chPeriod
    ,   chDigit_0, chDoubleQuote, chSpace, chLatin_e, chLatin_n, chLatin_c
    ,   chLatin_o, chLatin_d, chLatin_i, chLatin_n, chLatin_g, chEqual
    ,   chDoubleQuote, chNull
};

static const XMLCh  gXMLDecl2[] =
{
        chDoubleQuote, chSpace, chQuestion, chCloseAngle
    ,   chCR, chLF, chNull
};

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Constructors and Destructor
// ---------------------------------------------------------------------------
SAXPrintHandlers::SAXPrintHandlers( const   char* const              encodingName
                                    , const XMLFormatter::UnRepFlags unRepFlags) :

    fFormatter
    (
        encodingName
        , this
        , XMLFormatter::NoEscapes
        , unRepFlags
    )
{
    //
    //  Go ahead and output an XML Decl with our known encoding. This
    //  is not the best answer, but its the best we can do until we
    //  have SAX2 support.
    //
    fFormatter << gXMLDecl1 << fFormatter.getEncodingName() << gXMLDecl2;
}

SAXPrintHandlers::~SAXPrintHandlers()
{
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the output formatter target interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::writeChars(const XMLByte* const toWrite)
{
    // For this one, just dump them to the standard output
    cout << toWrite;
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX ErrorHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::error(const SAXParseException& e)
{
    cerr << "\nError at file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void SAXPrintHandlers::fatalError(const SAXParseException& e)
{
    cerr << "\nFatal Error at file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void SAXPrintHandlers::warning(const SAXParseException& e)
{
    cerr << "\nWarning at file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX DTDHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::unparsedEntityDecl(const     XMLCh* const name
                                          , const   XMLCh* const publicId
                                          , const   XMLCh* const systemId
                                          , const   XMLCh* const notationName)
{
    // Not used at this time
}

void SAXPrintHandlers::notationDecl(const   XMLCh* const name
                                    , const XMLCh* const publicId
                                    , const XMLCh* const systemId)
{
    // Not used at this time
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX DocumentHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::characters(const     XMLCh* const    chars
                                  , const   unsigned int    length)
{
    fFormatter.formatBuf(chars, length, XMLFormatter::CharEscapes);
}

void SAXPrintHandlers::endDocument()
{
}

void SAXPrintHandlers::endElement(const XMLCh* const name)
{
    fFormatter << gEndElement << name << chCloseAngle;
}

void SAXPrintHandlers::ignorableWhitespace( const   XMLCh* const chars
                                            ,const  unsigned int length)
{
    fFormatter.formatBuf(chars, length);
}

void SAXPrintHandlers::processingInstruction(const  XMLCh* const target
                                            , const XMLCh* const data)
{
    fFormatter << gStartPI << target;
    if (data)
        fFormatter << chSpace << data;
    fFormatter << gEndPI;
}

void SAXPrintHandlers::startDocument()
{
}

void SAXPrintHandlers::startElement(const   XMLCh* const    name
                                    ,       AttributeList&  attributes)
{
    // The name has to be representable without any escapes
    fFormatter  << XMLFormatter::NoEscapes
                << chOpenAngle << name;

    unsigned int len = attributes.getLength();
    for (unsigned int index = 0; index < len; index++)
    {
        //
        //  Again the name has to be completely representable. But the
        //  attribute can have refs and requires the attribute style
        //  escaping.
        //
        fFormatter  << XMLFormatter::NoEscapes
                    << chSpace << attributes.getName(index)
                    << chEqual << chDoubleQuote
                    << XMLFormatter::AttrEscapes
		            << attributes.getValue(index)
                    << XMLFormatter::NoEscapes
                    << chDoubleQuote;
    }
    fFormatter << chCloseAngle;
}
<commit_msg>A couple more tweaks of the event handler output.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.8  2000/04/07 23:25:53  roddey
 * A couple more tweaks of the event handler output.
 *
 * Revision 1.7  2000/04/06 19:09:51  roddey
 * Some more improvements to output formatting. Now it will correctly
 * handle doing the 'replacement char' style of dealing with chars
 * that are unrepresentable.
 *
 * Revision 1.6  2000/04/05 00:20:32  roddey
 * More updates for the low level formatted output support
 *
 * Revision 1.5  2000/03/28 19:43:11  roddey
 * Fixes for signed/unsigned warnings. New work for two way transcoding
 * stuff.
 *
 * Revision 1.4  2000/03/02 19:53:49  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.3  2000/02/11 03:05:35  abagchi
 * Removed second parameter from call to StrX constructor
 *
 * Revision 1.2  2000/02/06 07:47:24  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1.1.1  1999/11/09 01:09:29  twl
 * Initial checkin
 *
 * Revision 1.11  1999/11/08 20:43:42  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/XMLUni.hpp>
#include <sax/AttributeList.hpp>
#include "SAXPrint.hpp"

// ---------------------------------------------------------------------------
//  Local const data
//
//  Note: This is the 'safe' way to do these strings. If you compiler supports
//        L"" style strings, and portability is not a concern, you can use
//        those types constants directly.
// ---------------------------------------------------------------------------
static const XMLCh  gEndElement[] = { chOpenAngle, chForwardSlash, chNull };
static const XMLCh  gEndPI[] = { chQuestion, chCloseAngle, chSpace };
static const XMLCh  gStartPI[] = { chOpenAngle, chQuestion, chSpace };
static const XMLCh  gXMLDecl1[] =
{
        chOpenAngle, chQuestion, chLatin_x, chLatin_m, chLatin_l
    ,   chSpace, chLatin_v, chLatin_e, chLatin_r, chLatin_s, chLatin_i
    ,   chLatin_o, chLatin_n, chEqual, chDoubleQuote, chDigit_1, chPeriod
    ,   chDigit_0, chDoubleQuote, chSpace, chLatin_e, chLatin_n, chLatin_c
    ,   chLatin_o, chLatin_d, chLatin_i, chLatin_n, chLatin_g, chEqual
    ,   chDoubleQuote, chNull
};

static const XMLCh  gXMLDecl2[] =
{
        chDoubleQuote, chSpace, chQuestion, chCloseAngle
    ,   chCR, chLF, chNull
};

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Constructors and Destructor
// ---------------------------------------------------------------------------
SAXPrintHandlers::SAXPrintHandlers( const   char* const              encodingName
                                    , const XMLFormatter::UnRepFlags unRepFlags) :

    fFormatter
    (
        encodingName
        , this
        , XMLFormatter::NoEscapes
        , unRepFlags
    )
{
    //
    //  Go ahead and output an XML Decl with our known encoding. This
    //  is not the best answer, but its the best we can do until we
    //  have SAX2 support.
    //
    fFormatter << gXMLDecl1 << fFormatter.getEncodingName() << gXMLDecl2;
}

SAXPrintHandlers::~SAXPrintHandlers()
{
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the output formatter target interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::writeChars(const XMLByte* const toWrite)
{
    // For this one, just dump them to the standard output
    cout << toWrite;
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX ErrorHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::error(const SAXParseException& e)
{
    cerr << "\nError at file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void SAXPrintHandlers::fatalError(const SAXParseException& e)
{
    cerr << "\nFatal Error at file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

void SAXPrintHandlers::warning(const SAXParseException& e)
{
    cerr << "\nWarning at file " << StrX(e.getSystemId())
		 << ", line " << e.getLineNumber()
		 << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX DTDHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::unparsedEntityDecl(const     XMLCh* const name
                                          , const   XMLCh* const publicId
                                          , const   XMLCh* const systemId
                                          , const   XMLCh* const notationName)
{
    // Not used at this time
}

void SAXPrintHandlers::notationDecl(const   XMLCh* const name
                                    , const XMLCh* const publicId
                                    , const XMLCh* const systemId)
{
    // Not used at this time
}

// ---------------------------------------------------------------------------
//  SAXPrintHandlers: Overrides of the SAX DocumentHandler interface
// ---------------------------------------------------------------------------
void SAXPrintHandlers::characters(const     XMLCh* const    chars
                                  , const   unsigned int    length)
{
    fFormatter.formatBuf(chars, length, XMLFormatter::CharEscapes);
}

void SAXPrintHandlers::endDocument()
{
}

void SAXPrintHandlers::endElement(const XMLCh* const name)
{
    // No escapes are legal here
    fFormatter << XMLFormatter::NoEscapes << gEndElement << name << chCloseAngle;
}

void SAXPrintHandlers::ignorableWhitespace( const   XMLCh* const chars
                                            ,const  unsigned int length)
{
    fFormatter.formatBuf(chars, length, XMLFormatter::NoEscapes);
}

void SAXPrintHandlers::processingInstruction(const  XMLCh* const target
                                            , const XMLCh* const data)
{
    fFormatter << XMLFormatter::NoEscapes << gStartPI  << target;
    if (data)
        fFormatter << chSpace << data;
    fFormatter << XMLFormatter::NoEscapes << gEndPI;
}

void SAXPrintHandlers::startDocument()
{
}

void SAXPrintHandlers::startElement(const   XMLCh* const    name
                                    ,       AttributeList&  attributes)
{
    // The name has to be representable without any escapes
    fFormatter  << XMLFormatter::NoEscapes
                << chOpenAngle << name;

    unsigned int len = attributes.getLength();
    for (unsigned int index = 0; index < len; index++)
    {
        //
        //  Again the name has to be completely representable. But the
        //  attribute can have refs and requires the attribute style
        //  escaping.
        //
        fFormatter  << XMLFormatter::NoEscapes
                    << chSpace << attributes.getName(index)
                    << chEqual << chDoubleQuote
                    << XMLFormatter::AttrEscapes
		            << attributes.getValue(index)
                    << XMLFormatter::NoEscapes
                    << chDoubleQuote;
    }
    fFormatter << chCloseAngle;
}
<|endoftext|>


<commit_before>#include "pqrs/file_path.hpp"
#include "pqrs/vector.hpp"
#include <iostream>

namespace pqrs {
  namespace file_path {
    std::string
    combine(const std::string& path1,
            const std::string& path2)
    {
      return path1 + "/" + path2;
    }

    namespace {
      size_t
      get_dirname_position(const std::string& path, size_t pos = std::string::npos)
      {
        if (path.empty()) return 0;

        if (pos == std::string::npos) {
          pos = path.size() - 1;
        }

        if (path.size() <= pos) return 0;

        if (pos == 0) {
          // We retain the first slash for dirname("/") == "/".
          if (path[pos] == '/') {
            return 1;
          } else {
            return 0;
          }
        }

        if (path[pos] == '/') {
          --pos;
        }

        size_t i = path.rfind('/', pos);
        if (i == std::string::npos) {
          return 0;
        }
        if (i == 0) {
          // path starts with "/".
          return 1;
        }
        return i;
      }

      size_t
      process_dot(const std::string& path, size_t pos)
      {
        if (path.empty()) return pos;

        // foo/bar/./
        //          ^
        //         pos
        //
        if (pos > 2 &&
            path[pos - 2] == '/' &&
            path[pos - 1] == '.') {
          return pos - 2;
        }

        // ./foo/bar
        //  ^
        //  pos
        //
        if (pos == 1 &&
            path[0] == '.') {
          return 0;
        }

        return pos;
      }

      size_t
      process_dotdot(const std::string& path, size_t pos)
      {
        // foo/bar/../
        //           ^
        //          pos
        //
        if (pos > 2 &&
            path[pos - 3] == '/' &&
            path[pos - 2] == '.' &&
            path[pos - 1] == '.') {
          pos = get_dirname_position(path, pos - 3);

          // foo/bar/../
          //    ^
          //   pos

          return pos;
        }

        // ../foo/bar
        //   ^
        //  pos
        //
        if (pos == 2 &&
            path[0] == '.' &&
            path[1] == '.') {
          return 0;
        }

        return pos;
      }
    }

    std::string
    dirname(const std::string& path)
    {
      size_t pos = get_dirname_position(path);
      return path.substr(0, pos);
    }

    void
    normalize(std::string& path)
    {
      if (path.empty()) return;

      size_t end = path.size();
      size_t dest = 1;
      for (size_t src = 1; src < end; ++src) {
        // skip //
        if (path[dest - 1] == '/' && path[src] == '/') {
          continue;
        }

        // handling . and ..
        if (path[src] == '/') {
          for (int i = 0; i < 2; ++i) {
            size_t d = dest;
            switch (i) {
              case 0: d = process_dot(path, d);    break;
              case 1: d = process_dotdot(path, d); break;
            }
            if (dest != d) {
              dest = d;
            }
          }
          if (dest == 0) {
            if (path[dest] != '/') {
              continue;
            }
          } else {
            if (path[dest - 1] == '/') {
              continue;
            }
          }
        }

        if (dest != src) {
          path[dest] = path[src];
        }

        ++dest;
      }

      dest = process_dot(path, dest);
      dest = process_dotdot(path, dest);

      path.resize(dest);
    }
  }
}
<commit_msg>cleanup<commit_after>#include "pqrs/file_path.hpp"
#include "pqrs/vector.hpp"
#include <iostream>

namespace pqrs {
  namespace file_path {
    std::string
    combine(const std::string& path1,
            const std::string& path2)
    {
      return path1 + "/" + path2;
    }

    namespace {
      size_t
      get_dirname_position(const std::string& path, size_t pos = std::string::npos)
      {
        if (path.empty()) return 0;

        if (pos == std::string::npos) {
          pos = path.size() - 1;
        }

        if (path.size() <= pos) return 0;

        if (pos == 0) {
          // We retain the first slash for dirname("/") == "/".
          if (path[pos] == '/') {
            return 1;
          } else {
            return 0;
          }
        }

        if (path[pos] == '/') {
          --pos;
        }

        size_t i = path.rfind('/', pos);
        if (i == std::string::npos) {
          return 0;
        }
        if (i == 0) {
          // path starts with "/".
          return 1;
        }
        return i;
      }

      size_t
      process_dot(const std::string& path, size_t pos)
      {
        if (path.empty()) return pos;

        // foo/bar/./
        //          ^
        //         pos
        //
        if (pos > 2 &&
            path[pos - 2] == '/' &&
            path[pos - 1] == '.') {
          return pos - 2;
        }

        // ./foo/bar
        //  ^
        //  pos
        //
        if (pos == 1 &&
            path[0] == '.') {
          return 0;
        }

        return pos;
      }

      size_t
      process_dotdot(const std::string& path, size_t pos)
      {
        // foo/bar/../
        //           ^
        //          pos
        //
        if (pos > 2 &&
            path[pos - 3] == '/' &&
            path[pos - 2] == '.' &&
            path[pos - 1] == '.') {
          pos = get_dirname_position(path, pos - 3);

          // foo/bar/../
          //    ^
          //   pos

          return pos;
        }

        // ../foo/bar
        //   ^
        //  pos
        //
        if (pos == 2 &&
            path[0] == '.' &&
            path[1] == '.') {
          return 0;
        }

        return pos;
      }
    }

    std::string
    dirname(const std::string& path)
    {
      size_t pos = get_dirname_position(path);
      return path.substr(0, pos);
    }

    void
    normalize(std::string& path)
    {
      if (path.empty()) return;

      size_t end = path.size();
      size_t dest = 1;
      for (size_t src = 1; src < end; ++src) {
        // Skip multiple slashes.
        if (path[dest - 1] == '/' && path[src] == '/') {
          continue;
        }

        // Handling . and ..
        if (path[src] == '/') {
          dest = process_dot(path, dest);
          dest = process_dotdot(path, dest);

          if (dest == 0) {
            if (path[0] != '/') {
              continue;
            }
          } else {
            if (path[dest - 1] == '/') {
              continue;
            }
          }
        }

        if (dest != src) {
          path[dest] = path[src];
        }

        ++dest;
      }

      dest = process_dot(path, dest);
      dest = process_dotdot(path, dest);

      path.resize(dest);
    }
  }
}
<|endoftext|>


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

#ifndef _XMLOFF_RENAMEELEMTCONTEXT_HXX
#define _XMLOFF_RENAMEELEMTCONTEXT_HXX

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif
#ifndef _XMLOFF_TRANSFORMERCONTEXT_HXX
#include "TransformerContext.hxx"
#endif

class XMLRenameElemTransformerContext : public XMLTransformerContext
{
    ::rtl::OUString m_aElemQName;
    ::rtl::OUString m_aAttrQName;
    ::rtl::OUString m_aAttrValue;

public:
    TYPEINFO();

    // The following consutructor renames the element names "rQName"
    // to bPrefix/eToken
    XMLRenameElemTransformerContext( XMLTransformerBase& rTransformer,
                           const ::rtl::OUString& rQName,
                              sal_uInt16 nPrefix,
                              ::xmloff::token::XMLTokenEnum eToken  );

    // The following consutructor renames the element names "rQName"
    // to bPrefix/eToken and adds an attribute nAPrefix/eAToken that has
    // the value eVToken.
    XMLRenameElemTransformerContext( XMLTransformerBase& rTransformer,
                           const ::rtl::OUString& rQName,
                              sal_uInt16 nPrefix,
                              ::xmloff::token::XMLTokenEnum eToken,
                              sal_uInt16 nAPrefix,
                              ::xmloff::token::XMLTokenEnum eAToken,
                              ::xmloff::token::XMLTokenEnum eVToken );

    // A contexts destructor does anything that is required if an element
    // ends. By default, nothing is done.
    // Note that virtual methods cannot be used inside destructors. Use
    // EndElement instead if this is required.
    virtual ~XMLRenameElemTransformerContext();

    virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
    virtual void EndElement();
};

#endif  //  _XMLOFF_RENAMEELEMCONTEXT_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.300); FILE MERGED 2005/09/05 14:40:29 rt 1.2.300.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: RenameElemTContext.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 15:55:03 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_RENAMEELEMTCONTEXT_HXX
#define _XMLOFF_RENAMEELEMTCONTEXT_HXX

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif
#ifndef _XMLOFF_TRANSFORMERCONTEXT_HXX
#include "TransformerContext.hxx"
#endif

class XMLRenameElemTransformerContext : public XMLTransformerContext
{
    ::rtl::OUString m_aElemQName;
    ::rtl::OUString m_aAttrQName;
    ::rtl::OUString m_aAttrValue;

public:
    TYPEINFO();

    // The following consutructor renames the element names "rQName"
    // to bPrefix/eToken
    XMLRenameElemTransformerContext( XMLTransformerBase& rTransformer,
                           const ::rtl::OUString& rQName,
                              sal_uInt16 nPrefix,
                              ::xmloff::token::XMLTokenEnum eToken  );

    // The following consutructor renames the element names "rQName"
    // to bPrefix/eToken and adds an attribute nAPrefix/eAToken that has
    // the value eVToken.
    XMLRenameElemTransformerContext( XMLTransformerBase& rTransformer,
                           const ::rtl::OUString& rQName,
                              sal_uInt16 nPrefix,
                              ::xmloff::token::XMLTokenEnum eToken,
                              sal_uInt16 nAPrefix,
                              ::xmloff::token::XMLTokenEnum eAToken,
                              ::xmloff::token::XMLTokenEnum eVToken );

    // A contexts destructor does anything that is required if an element
    // ends. By default, nothing is done.
    // Note that virtual methods cannot be used inside destructors. Use
    // EndElement instead if this is required.
    virtual ~XMLRenameElemTransformerContext();

    virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
    virtual void EndElement();
};

#endif  //  _XMLOFF_RENAMEELEMCONTEXT_HXX

<|endoftext|>


<commit_before>
#include "math.h"

#include <sstream>
#include <limits>
#include <stdexcept>

#include "glps_parser.h"
#include "scsi/config.h"

namespace {
// Numeric operations

int unary_negate(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = -boost::get<double>(A[0]->value);
    return 0;
}

int unary_sin(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = sin(boost::get<double>(A[0]->value));
    return 0;
}
int unary_cos(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = cos(boost::get<double>(A[0]->value));
    return 0;
}
int unary_tan(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = tan(boost::get<double>(A[0]->value));
    return 0;
}
int unary_asin(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = asin(boost::get<double>(A[0]->value));
    return 0;
}
int unary_acos(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = acos(boost::get<double>(A[0]->value));
    return 0;
}
int unary_atan(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = atan(boost::get<double>(A[0]->value));
    return 0;
}

int binary_add(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = boost::get<double>(A[0]->value)+boost::get<double>(A[1]->value);
    return 0;
}
int binary_sub(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = boost::get<double>(A[0]->value)-boost::get<double>(A[1]->value);
    return 0;
}
int binary_mult(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = boost::get<double>(A[0]->value)*boost::get<double>(A[1]->value);
    return 0;
}
int binary_div(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    double result = boost::get<double>(A[0]->value)/boost::get<double>(A[1]->value);
    if(!isfinite(result)) {
        ctxt->last_error = "division results in non-finite value";
        return 1;
    }
    *R = result;
    return 0;
}

// beamline operations

int unary_bl_negate(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    // reverse the order of the beamline
    const std::vector<std::string>& line = boost::get<std::vector<std::string> >(A[0]->value);
    std::vector<std::string> ret(line.size());
    std::copy(line.rbegin(),
              line.rend(),
              ret.begin());
    *R = ret;
    return 0;
}

template<int MULT, int LINE>
int binary_bl_mult(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    // multiple of scale * beamline repeats the beamline 'scale' times
    assert(A[MULT]->etype==glps_expr_number);
    assert(A[LINE]->etype==glps_expr_line);

    double factor = boost::get<double>(A[MULT]->value);

    if(factor<0.0 || factor>std::numeric_limits<unsigned>::max()) {
        ctxt->last_error = "beamline scale by negative value or out of range value";
        return 1;
    }
    unsigned factori = (unsigned)factor;

    const std::vector<std::string>& line = boost::get<std::vector<std::string> >(A[LINE]->value);

    std::vector<std::string> ret(line.size()*factori);

    if(factori>0)
    {
        std::vector<std::string>::iterator outi = ret.begin();

        while(factori--)
            outi = std::copy(line.begin(),
                             line.end(),
                             outi);
    }
    *R = ret;
    return 0;
}

int unary_parse(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    assert(A[0]->etype==glps_expr_string);
    const std::string& name = boost::get<std::string>(A[0]->value);

    GLPSParser P;
    P.setPrinter(ctxt->printer);

    boost::shared_ptr<Config> ret(P.parse_file(name.c_str()));
    *R = ret;
    return 0;
}

int unary_file(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    using namespace boost::filesystem;
    const std::string& inp = boost::get<std::string>(A[0]->value);
    path ret(canonical(inp, ctxt->cwd));

    if(!exists(ret)) {
        std::ostringstream strm;
        strm<<"\""<<ret<<"\" does not exist";
        ctxt->last_error = strm.str();
        return 1;
    }

    *R = ret.native();
    return 0;
}

int unary_h5file(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    using namespace boost::filesystem;
    const std::string& inp = boost::get<std::string>(A[0]->value);

    /* The provided spec may contain both file path and group(s)
     * seperated by '/' which is ambigious as the file path
     * may contain '/' as well...
     * so do as h5ls does and strip off from the right hand side until
     * and try to open while '/' remain.
     */
    size_t sep = inp.npos;

    while(true) {
        sep = inp.find_last_of('/', sep-1);

        path fname(absolute(inp.substr(0, sep), ctxt->cwd));

        if(exists(fname)) {
            *R = canonical(fname).native() + inp.substr(sep);
            return 0;
        } else if(sep==inp.npos) {
            break;
        }
    }

    std::ostringstream strm;
    strm<<"\""<<inp<<"\" does not exist";
    ctxt->last_error = strm.str();
    return 1;
}

} // namespace

parse_context::parse_context(const char *path)
    :last_line(0), printer(NULL), error_scratch(300), scanner(NULL)
{
    if(path)
        cwd = boost::filesystem::canonical(path);
    else
        cwd = boost::filesystem::current_path();
    addop("-", &unary_negate, glps_expr_number, 1, glps_expr_number);

    addop("sin", &unary_sin, glps_expr_number, 1, glps_expr_number);
    addop("cos", &unary_cos, glps_expr_number, 1, glps_expr_number);
    addop("tan", &unary_tan, glps_expr_number, 1, glps_expr_number);
    addop("asin",&unary_asin,glps_expr_number, 1, glps_expr_number);
    addop("acos",&unary_acos,glps_expr_number, 1, glps_expr_number);
    addop("atan",&unary_atan,glps_expr_number, 1, glps_expr_number);
    // aliases to capture legacy behavour :P
    addop("arcsin",&unary_asin,glps_expr_number, 1, glps_expr_number);
    addop("arccos",&unary_acos,glps_expr_number, 1, glps_expr_number);
    addop("arctan",&unary_atan,glps_expr_number, 1, glps_expr_number);

    addop("+", &binary_add, glps_expr_number, 2, glps_expr_number, glps_expr_number);
    addop("-", &binary_sub, glps_expr_number, 2, glps_expr_number, glps_expr_number);
    addop("*", &binary_mult,glps_expr_number, 2, glps_expr_number, glps_expr_number);
    addop("/", &binary_div, glps_expr_number, 2, glps_expr_number, glps_expr_number);

    addop("-", &unary_bl_negate, glps_expr_line, 1, glps_expr_line);

    addop("*", &binary_bl_mult<0,1>, glps_expr_line, 2, glps_expr_number, glps_expr_line);
    addop("*", &binary_bl_mult<1,0>, glps_expr_line, 2, glps_expr_line, glps_expr_number);

    addop("parse", &unary_parse, glps_expr_config, 1, glps_expr_string);
    addop("file", &unary_file, glps_expr_string, 1, glps_expr_string);
    addop("h5file", &unary_h5file, glps_expr_string, 1, glps_expr_string);
}

parse_context::~parse_context()
{
}

<commit_msg>parse() handle relative path<commit_after>
#include "math.h"

#include <sstream>
#include <limits>
#include <stdexcept>

#include "glps_parser.h"
#include "scsi/config.h"

namespace {
// Numeric operations

int unary_negate(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = -boost::get<double>(A[0]->value);
    return 0;
}

int unary_sin(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = sin(boost::get<double>(A[0]->value));
    return 0;
}
int unary_cos(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = cos(boost::get<double>(A[0]->value));
    return 0;
}
int unary_tan(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = tan(boost::get<double>(A[0]->value));
    return 0;
}
int unary_asin(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = asin(boost::get<double>(A[0]->value));
    return 0;
}
int unary_acos(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = acos(boost::get<double>(A[0]->value));
    return 0;
}
int unary_atan(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = atan(boost::get<double>(A[0]->value));
    return 0;
}

int binary_add(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = boost::get<double>(A[0]->value)+boost::get<double>(A[1]->value);
    return 0;
}
int binary_sub(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = boost::get<double>(A[0]->value)-boost::get<double>(A[1]->value);
    return 0;
}
int binary_mult(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    *R = boost::get<double>(A[0]->value)*boost::get<double>(A[1]->value);
    return 0;
}
int binary_div(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    double result = boost::get<double>(A[0]->value)/boost::get<double>(A[1]->value);
    if(!isfinite(result)) {
        ctxt->last_error = "division results in non-finite value";
        return 1;
    }
    *R = result;
    return 0;
}

// beamline operations

int unary_bl_negate(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    // reverse the order of the beamline
    const std::vector<std::string>& line = boost::get<std::vector<std::string> >(A[0]->value);
    std::vector<std::string> ret(line.size());
    std::copy(line.rbegin(),
              line.rend(),
              ret.begin());
    *R = ret;
    return 0;
}

template<int MULT, int LINE>
int binary_bl_mult(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    // multiple of scale * beamline repeats the beamline 'scale' times
    assert(A[MULT]->etype==glps_expr_number);
    assert(A[LINE]->etype==glps_expr_line);

    double factor = boost::get<double>(A[MULT]->value);

    if(factor<0.0 || factor>std::numeric_limits<unsigned>::max()) {
        ctxt->last_error = "beamline scale by negative value or out of range value";
        return 1;
    }
    unsigned factori = (unsigned)factor;

    const std::vector<std::string>& line = boost::get<std::vector<std::string> >(A[LINE]->value);

    std::vector<std::string> ret(line.size()*factori);

    if(factori>0)
    {
        std::vector<std::string>::iterator outi = ret.begin();

        while(factori--)
            outi = std::copy(line.begin(),
                             line.end(),
                             outi);
    }
    *R = ret;
    return 0;
}

int unary_parse(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    using namespace boost::filesystem;
    assert(A[0]->etype==glps_expr_string);
    path name(canonical(boost::get<std::string>(A[0]->value), ctxt->cwd));

    GLPSParser P;
    P.setPrinter(ctxt->printer);

    boost::shared_ptr<Config> ret(P.parse_file(name.native().c_str()));
    *R = ret;
    return 0;
}

int unary_file(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    using namespace boost::filesystem;
    const std::string& inp = boost::get<std::string>(A[0]->value);
    path ret(canonical(inp, ctxt->cwd));

    if(!exists(ret)) {
        std::ostringstream strm;
        strm<<"\""<<ret<<"\" does not exist";
        ctxt->last_error = strm.str();
        return 1;
    }

    *R = ret.native();
    return 0;
}

int unary_h5file(parse_context* ctxt, expr_value_t *R, const expr_t * const *A)
{
    using namespace boost::filesystem;
    const std::string& inp = boost::get<std::string>(A[0]->value);

    /* The provided spec may contain both file path and group(s)
     * seperated by '/' which is ambigious as the file path
     * may contain '/' as well...
     * so do as h5ls does and strip off from the right hand side until
     * and try to open while '/' remain.
     */
    size_t sep = inp.npos;

    while(true) {
        sep = inp.find_last_of('/', sep-1);

        path fname(absolute(inp.substr(0, sep), ctxt->cwd));

        if(exists(fname)) {
            *R = canonical(fname).native() + inp.substr(sep);
            return 0;
        } else if(sep==inp.npos) {
            break;
        }
    }

    std::ostringstream strm;
    strm<<"\""<<inp<<"\" does not exist";
    ctxt->last_error = strm.str();
    return 1;
}

} // namespace

parse_context::parse_context(const char *path)
    :last_line(0), printer(NULL), error_scratch(300), scanner(NULL)
{
    if(path)
        cwd = boost::filesystem::canonical(path);
    else
        cwd = boost::filesystem::current_path();
    addop("-", &unary_negate, glps_expr_number, 1, glps_expr_number);

    addop("sin", &unary_sin, glps_expr_number, 1, glps_expr_number);
    addop("cos", &unary_cos, glps_expr_number, 1, glps_expr_number);
    addop("tan", &unary_tan, glps_expr_number, 1, glps_expr_number);
    addop("asin",&unary_asin,glps_expr_number, 1, glps_expr_number);
    addop("acos",&unary_acos,glps_expr_number, 1, glps_expr_number);
    addop("atan",&unary_atan,glps_expr_number, 1, glps_expr_number);
    // aliases to capture legacy behavour :P
    addop("arcsin",&unary_asin,glps_expr_number, 1, glps_expr_number);
    addop("arccos",&unary_acos,glps_expr_number, 1, glps_expr_number);
    addop("arctan",&unary_atan,glps_expr_number, 1, glps_expr_number);

    addop("+", &binary_add, glps_expr_number, 2, glps_expr_number, glps_expr_number);
    addop("-", &binary_sub, glps_expr_number, 2, glps_expr_number, glps_expr_number);
    addop("*", &binary_mult,glps_expr_number, 2, glps_expr_number, glps_expr_number);
    addop("/", &binary_div, glps_expr_number, 2, glps_expr_number, glps_expr_number);

    addop("-", &unary_bl_negate, glps_expr_line, 1, glps_expr_line);

    addop("*", &binary_bl_mult<0,1>, glps_expr_line, 2, glps_expr_number, glps_expr_line);
    addop("*", &binary_bl_mult<1,0>, glps_expr_line, 2, glps_expr_line, glps_expr_number);

    addop("parse", &unary_parse, glps_expr_config, 1, glps_expr_string);
    addop("file", &unary_file, glps_expr_string, 1, glps_expr_string);
    addop("h5file", &unary_h5file, glps_expr_string, 1, glps_expr_string);
}

parse_context::~parse_context()
{
}

<|endoftext|>


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

#include <algorithm>
#include <cassert>

#include "boost/format.hpp"
#include "boost/lexical_cast.hpp"
#include "boost/regex.hpp"
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include "boost/filesystem/convenience.hpp"
#include "boost/algorithm/string.hpp"

#include "IECore/Exception.h"
#include "IECore/FileSequence.h"
#include "IECore/FileSequenceFunctions.h"
#include "IECore/CompoundFrameList.h"
#include "IECore/EmptyFrameList.h"
#include "IECore/FrameRange.h"

using namespace IECore;

void IECore::findSequences( const std::vector< std::string > &names, std::vector< FileSequencePtr > &sequences )
{
	sequences.clear();

	/// this matches names of the form $prefix$frameNumber$suffix
	/// placing each of those in a group of the resulting match.
	/// both $prefix and $suffix may be the empty string and $frameNumber
	/// may be preceded by a minus sign.
	boost::regex matchExpression( std::string( "^([^#]*?)(-?[0-9]+)([^0-9#]*)$" ) );

	/// build a mapping from ($prefix, $suffix) to a list of $frameNumbers
	typedef std::vector< std::string > Frames;
	typedef std::map< std::pair< std::string, std::string >, Frames > SequenceMap;

	SequenceMap sequenceMap;

	for ( std::vector< std::string >::const_iterator it = names.begin(); it != names.end(); ++it )
	{
		boost::smatch matches;
		if ( boost::regex_match( *it, matches, matchExpression ) )
		{
			sequenceMap[
				SequenceMap::key_type(
					std::string( matches[1].first, matches[1].second ),
					std::string( matches[3].first, matches[3].second )
				)
			].push_back( std::string( matches[2].first, matches[2].second ) );
		}
	}

	for ( SequenceMap::const_iterator it = sequenceMap.begin(); it != sequenceMap.end(); ++it )
	{
		const SequenceMap::key_type &fixes = it->first;
		const Frames &frames = it->second;

		/// in diabolical cases the elements of frames may not all have the same padding
		/// so we'll sort them out into padded and unpadded frame sequences here, by creating
		/// a map of padding->list of frames. unpadded things will be considered to have a padding
		/// of 1.
		typedef std::vector< FrameList::Frame > NumericFrames;
		typedef std::map< unsigned int, NumericFrames > PaddingToFramesMap;
		PaddingToFramesMap paddingToFrames;
		for ( Frames::const_iterator fIt = frames.begin(); fIt != frames.end(); ++fIt )
		{
			std::string frame = *fIt;
			int sign = 1;

			assert( frame.size() );
			if ( *frame.begin() == '-' )
			{
				frame = frame.substr( 1, frame.size() - 1 );
				sign = -1;
			}
			if ( *frame.begin() == '0' || paddingToFrames.find( frame.size() ) != paddingToFrames.end() )
			{
				paddingToFrames[ frame.size() ].push_back( sign * boost::lexical_cast<FrameList::Frame>( frame ) );
			}
			else
			{
				paddingToFrames[ 1 ].push_back( sign * boost::lexical_cast<FrameList::Frame>( frame ) );
			}
		}

		for ( PaddingToFramesMap::iterator pIt = paddingToFrames.begin(); pIt != paddingToFrames.end(); ++pIt )
		{
			const PaddingToFramesMap::key_type &padding = pIt->first;
			NumericFrames &numericFrames = pIt->second;
			std::sort( numericFrames.begin(), numericFrames.end() );

			FrameListPtr frameList = frameListFromList( numericFrames );

			std::vector< FrameList::Frame > expandedFrameList;
			frameList->asList( expandedFrameList );

			/// remove any sequences with less than two files
			if ( expandedFrameList.size() >= 2 )
			{
				std::string frameTemplate;
				for ( PaddingToFramesMap::key_type i = 0; i < padding; i++ )
				{
					frameTemplate += "#";
				}

				sequences.push_back(
					new FileSequence(
						fixes.first + frameTemplate + fixes.second,
						frameList
					)
				);
			}
		}
	}
}

void IECore::ls( const std::string &path, std::vector< FileSequencePtr > &sequences )
{
	sequences.clear();

	 if ( boost::filesystem::is_directory( path ) )
	 {
		boost::filesystem::directory_iterator end;
	 	std::vector< std::string > files;
		for ( boost::filesystem::directory_iterator it( path ); it != end; ++it )
		{
			files.push_back( it->leaf() );
		}

		findSequences( files, sequences );
	 }
}

void IECore::ls( const std::string &sequencePath, FileSequencePtr &sequence )
{
	sequence = 0;
	boost::smatch matches;
	bool m = boost::regex_match( sequencePath, matches, FileSequence::fileNameValidator() );
	if ( !m )
	{
		return;
	}

	const std::string paddingStr( matches[2].first, matches[2].second );
	const unsigned padding = paddingStr.size();

 	std::vector< std::string > files;

	boost::filesystem::path dir = boost::filesystem::path( sequencePath ).parent_path();

	std::string baseSequencePath = boost::filesystem::path( sequencePath ).filename();

	const std::string::size_type first = baseSequencePath.find_first_of( '#' );
	assert( first != std::string::npos );
	const std::string prefix = baseSequencePath.substr( 0, first );

	const std::string::size_type last = baseSequencePath.find_last_of( '#' );
	assert( last != std::string::npos );
	const std::string suffix = baseSequencePath.substr( last + 1, baseSequencePath.size() - last - 1 );

	boost::filesystem::path dirToCheck( dir );
	if ( dirToCheck.string() == "" )
	{
		dirToCheck = ".";
	}

	boost::filesystem::directory_iterator end;
	for ( boost::filesystem::directory_iterator it( dirToCheck ); it != end; ++it )
	{
		const std::string &fileName = it->leaf();

		if ( fileName.substr( 0, prefix.size() ) == prefix && fileName.substr( fileName.size() - suffix.size(), suffix.size() ) == suffix )
		{
			files.push_back( ( dir / fileName ).string() );
		}
	}

	std::vector< FileSequencePtr > sequences;
	findSequences( files, sequences );

	for ( std::vector< FileSequencePtr >::iterator it = sequences.begin(); it != sequences.end() ; ++it )
	{
		if ( (*it)->getPadding() == padding )
		{
			sequence = *it;
			return;
		}
	}
}

FrameListPtr IECore::frameListFromList( const std::vector< FrameList::Frame > &frames )
{
	if ( frames.size() == 0 )
	{
		return new EmptyFrameList();
	}
	else if ( frames.size() == 1 )
	{
		return new FrameRange( frames[0], frames[0] );
	}

	std::vector< FrameListPtr > frameLists;

	FrameList::Frame rangeStart = 0;
	FrameList::Frame rangeEnd = 1;
	FrameList::Frame rangeStep = frames[ rangeEnd ] - frames[ rangeStart ];
	assert( rangeStep > 0 );

	while ( rangeEnd <= frames.size() )
	{
		if ( rangeEnd == frames.size() || frames[ rangeEnd ] - frames[ rangeEnd -1 ] != rangeStep )
		{
			/// we've come to the end of a run
			if ( rangeEnd - 1 == rangeStart )
			{
				frameLists.push_back( new FrameRange( frames[ rangeStart ], frames[ rangeStart ] ) );
			}
			else
			{
				frameLists.push_back( new FrameRange( frames[ rangeStart ], frames[ rangeEnd -1 ], rangeStep ) );
			}

			rangeStart = rangeEnd;
			rangeEnd = rangeStart + 1;

			if ( rangeEnd < frames.size() )
			{
				rangeStep = frames[ rangeEnd ] - frames[ rangeStart ];
			}
		}
		else
		{
			rangeEnd ++;
		}
	}

	if ( frameLists.size() == 1 )
	{
		return frameLists[0];
	}
	else
	{
		return new CompoundFrameList( frameLists );
	}

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

#include <algorithm>
#include <cassert>

#include "boost/format.hpp"
#include "boost/lexical_cast.hpp"
#include "boost/regex.hpp"
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include "boost/filesystem/convenience.hpp"
#include "boost/algorithm/string.hpp"

#include "IECore/Exception.h"
#include "IECore/FileSequence.h"
#include "IECore/FileSequenceFunctions.h"
#include "IECore/CompoundFrameList.h"
#include "IECore/EmptyFrameList.h"
#include "IECore/FrameRange.h"

using namespace IECore;

void IECore::findSequences( const std::vector< std::string > &names, std::vector< FileSequencePtr > &sequences )
{
	sequences.clear();

	/// this matches names of the form $prefix$frameNumber$suffix
	/// placing each of those in a group of the resulting match.
	/// both $prefix and $suffix may be the empty string and $frameNumber
	/// may be preceded by a minus sign.
	boost::regex matchExpression( std::string( "^([^#]*?)(-?[0-9]+)([^0-9#]*)$" ) );

	/// build a mapping from ($prefix, $suffix) to a list of $frameNumbers
	typedef std::vector< std::string > Frames;
	typedef std::map< std::pair< std::string, std::string >, Frames > SequenceMap;

	SequenceMap sequenceMap;

	for ( std::vector< std::string >::const_iterator it = names.begin(); it != names.end(); ++it )
	{
		boost::smatch matches;
		if ( boost::regex_match( *it, matches, matchExpression ) )
		{
			sequenceMap[
				SequenceMap::key_type(
					std::string( matches[1].first, matches[1].second ),
					std::string( matches[3].first, matches[3].second )
				)
			].push_back( std::string( matches[2].first, matches[2].second ) );
		}
	}

	for ( SequenceMap::const_iterator it = sequenceMap.begin(); it != sequenceMap.end(); ++it )
	{
		const SequenceMap::key_type &fixes = it->first;
		const Frames &frames = it->second;

		/// in diabolical cases the elements of frames may not all have the same padding
		/// so we'll sort them out into padded and unpadded frame sequences here, by creating
		/// a map of padding->list of frames. unpadded things will be considered to have a padding
		/// of 1.
		typedef std::vector< FrameList::Frame > NumericFrames;
		typedef std::map< unsigned int, NumericFrames > PaddingToFramesMap;
		PaddingToFramesMap paddingToFrames;
		for ( Frames::const_iterator fIt = frames.begin(); fIt != frames.end(); ++fIt )
		{
			std::string frame = *fIt;
			int sign = 1;

			assert( frame.size() );
			if ( *frame.begin() == '-' )
			{
				frame = frame.substr( 1, frame.size() - 1 );
				sign = -1;
			}
			if ( *frame.begin() == '0' || paddingToFrames.find( frame.size() ) != paddingToFrames.end() )
			{
				paddingToFrames[ frame.size() ].push_back( sign * boost::lexical_cast<FrameList::Frame>( frame ) );
			}
			else
			{
				paddingToFrames[ 1 ].push_back( sign * boost::lexical_cast<FrameList::Frame>( frame ) );
			}
		}

		for ( PaddingToFramesMap::iterator pIt = paddingToFrames.begin(); pIt != paddingToFrames.end(); ++pIt )
		{
			const PaddingToFramesMap::key_type &padding = pIt->first;
			NumericFrames &numericFrames = pIt->second;
			std::sort( numericFrames.begin(), numericFrames.end() );

			FrameListPtr frameList = frameListFromList( numericFrames );

			std::vector< FrameList::Frame > expandedFrameList;
			frameList->asList( expandedFrameList );

			/// remove any sequences with less than two files
			if ( expandedFrameList.size() >= 2 )
			{
				std::string frameTemplate;
				for ( PaddingToFramesMap::key_type i = 0; i < padding; i++ )
				{
					frameTemplate += "#";
				}

				sequences.push_back(
					new FileSequence(
						fixes.first + frameTemplate + fixes.second,
						frameList
					)
				);
			}
		}
	}
}

void IECore::ls( const std::string &path, std::vector< FileSequencePtr > &sequences )
{
	sequences.clear();

	 if ( boost::filesystem::is_directory( path ) )
	 {
		boost::filesystem::directory_iterator end;
	 	std::vector< std::string > files;
		for ( boost::filesystem::directory_iterator it( path ); it != end; ++it )
		{
			files.push_back( it->leaf() );
		}

		findSequences( files, sequences );
	 }
}

void IECore::ls( const std::string &sequencePath, FileSequencePtr &sequence )
{
	sequence = 0;
	boost::smatch matches;
	bool m = boost::regex_match( sequencePath, matches, FileSequence::fileNameValidator() );
	if ( !m )
	{
		return;
	}

	const std::string paddingStr( matches[2].first, matches[2].second );
	const unsigned padding = paddingStr.size();

 	std::vector< std::string > files;

	boost::filesystem::path dir = boost::filesystem::path( sequencePath ).parent_path();

	std::string baseSequencePath = boost::filesystem::path( sequencePath ).filename();

	const std::string::size_type first = baseSequencePath.find_first_of( '#' );
	assert( first != std::string::npos );
	const std::string prefix = baseSequencePath.substr( 0, first );

	const std::string::size_type last = baseSequencePath.find_last_of( '#' );
	assert( last != std::string::npos );
	const std::string suffix = baseSequencePath.substr( last + 1, baseSequencePath.size() - last - 1 );

	boost::filesystem::path dirToCheck( dir );
	if ( dirToCheck.string() == "" )
	{
		dirToCheck = ".";
	}

	boost::filesystem::directory_iterator end;
	for ( boost::filesystem::directory_iterator it( dirToCheck ); it != end; ++it )
	{
		const std::string &fileName = it->leaf();

		if ( fileName.substr( 0, prefix.size() ) == prefix && fileName.substr( fileName.size() - suffix.size(), suffix.size() ) == suffix )
		{
			files.push_back( ( dir / fileName ).string() );
		}
	}

	std::vector< FileSequencePtr > sequences;
	findSequences( files, sequences );

	for ( std::vector< FileSequencePtr >::iterator it = sequences.begin(); it != sequences.end() ; ++it )
	{
		if ( (*it)->getPadding() == padding )
		{
			sequence = *it;
			return;
		}
	}
}

FrameListPtr IECore::frameListFromList( const std::vector< FrameList::Frame > &frames )
{
	if ( frames.size() == 0 )
	{
		return new EmptyFrameList();
	}
	else if ( frames.size() == 1 )
	{
		return new FrameRange( frames[0], frames[0] );
	}

	std::vector< FrameListPtr > frameLists;

	FrameList::Frame rangeStart = 0;
	FrameList::Frame rangeEnd = 1;
	FrameList::Frame rangeStep = frames[ rangeEnd ] - frames[ rangeStart ];
	assert( rangeStep > 0 );

	while ( rangeEnd <= (FrameList::Frame)frames.size() )
	{
		if ( rangeEnd == (FrameList::Frame)frames.size() || frames[ rangeEnd ] - frames[ rangeEnd -1 ] != rangeStep )
		{
			/// we've come to the end of a run
			if ( rangeEnd - 1 == rangeStart )
			{
				frameLists.push_back( new FrameRange( frames[ rangeStart ], frames[ rangeStart ] ) );
			}
			else
			{
				frameLists.push_back( new FrameRange( frames[ rangeStart ], frames[ rangeEnd -1 ], rangeStep ) );
			}

			rangeStart = rangeEnd;
			rangeEnd = rangeStart + 1;

			if ( rangeEnd < (FrameList::Frame)frames.size() )
			{
				rangeStep = frames[ rangeEnd ] - frames[ rangeStart ];
			}
		}
		else
		{
			rangeEnd ++;
		}
	}

	if ( frameLists.size() == 1 )
	{
		return frameLists[0];
	}
	else
	{
		return new CompoundFrameList( frameLists );
	}

}
<|endoftext|>