Ejemplo n.º 1
0
void IStreams::init()
{
    // simple temporary endian check
    union {
        Util::uint32_t l;
        char c[4];
    } u;

    u.l = 0x01234567;

    if (u.c[0] != 0x67)
    {
        throw std::runtime_error(
            "Ogawa currently only supports little-endian reading.");
    }

    if (mData->streams.empty())
    {
        return;
    }

    Alembic::Util::uint64_t firstGroupPos = 0;

    for (std::size_t i = 0; i < mData->streams.size(); ++i)
    {
        char header[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        mData->offsets.push_back(mData->streams[i]->tellg());
        mData->streams[i]->read(header, 16);
        std::string magicStr(header, 5);
        if (magicStr != "Ogawa")
        {
            mData->frozen = false;
            mData->valid = false;
            mData->version = 0;
            return;
        }
        bool frozen = (header[5] == char(0xff));
        Alembic::Util::uint16_t version = (header[6] << 8) | header[7];
        Alembic::Util::uint64_t groupPos =
            *((Alembic::Util::uint64_t *)(&(header[8])));

        if (i == 0)
        {
            firstGroupPos = groupPos;
            mData->frozen = frozen;
            mData->version = version;
        }
        // all the streams have to agree, or we are invalid
        else if (firstGroupPos != groupPos || mData->frozen != frozen ||
                 mData->version != version)
        {
            mData->frozen = false;
            mData->valid = false;
            mData->version = 0;
            return;
        }
    }
    mData->valid = true;
}
Ejemplo n.º 2
0
  Interpreter::CompilationResult
  MetaProcessor::readInputFromFile(llvm::StringRef filename,
                                   Value* result,
                                   bool ignoreOutmostBlock /*=false*/) {

    {
      // check that it's not binary:
      std::ifstream in(filename.str().c_str(), std::ios::in | std::ios::binary);
      char magic[1024] = {0};
      in.read(magic, sizeof(magic));
      size_t readMagic = in.gcount();
      if (readMagic >= 4) {
        llvm::StringRef magicStr(magic,in.gcount());
        llvm::sys::fs::file_magic fileType
          = llvm::sys::fs::identify_magic(magicStr);
        if (fileType != llvm::sys::fs::file_magic::unknown) {
          llvm::errs() << "Error in cling::MetaProcessor: "
            "cannot read input from a binary file!\n";
          return Interpreter::kFailure;
        }
        unsigned printable = 0;
        for (size_t i = 0; i < readMagic; ++i)
          if (isprint(magic[i]))
            ++printable;
        if (10 * printable <  5 * readMagic) {
          // 50% printable for ASCII files should be a safe guess.
          llvm::errs() << "Error in cling::MetaProcessor: "
            "cannot read input from a (likely) binary file!\n" << printable;
          return Interpreter::kFailure;
        }
      }
    }

    std::ifstream in(filename.str().c_str());
    in.seekg(0, std::ios::end);
    size_t size = in.tellg();
    std::string content(size, ' ');
    in.seekg(0);
    in.read(&content[0], size);

    if (ignoreOutmostBlock && !content.empty()) {
      static const char whitespace[] = " \t\r\n";
      std::string::size_type posNonWS = content.find_first_not_of(whitespace);
      // Handle comments before leading {
      while (content[posNonWS] == '/' && content[posNonWS+1] == '/') {
        // Remove the comment line
        posNonWS = content.find_first_of('\n', posNonWS+2)+1;
      }
      std::string::size_type replaced = posNonWS;
      if (posNonWS != std::string::npos) {
        if (content[posNonWS] == '{') {
          // hide the curly brace:
          content[posNonWS] = ' ';
          // and the matching closing '}'
          posNonWS = content.find_last_not_of(whitespace);
          if (posNonWS != std::string::npos) {
            if (content[posNonWS] == ';' && content[posNonWS-1] == '}') {
              content[posNonWS--] = ' '; // replace ';' and enter next if
            }
            if (content[posNonWS] == '}') {
              content[posNonWS] = ' '; // replace '}'
            } else {
              std::string::size_type posComment = content.find_last_of('}');
                if (content[posComment] == '}') {
                  content[posComment] = ' '; // replace '}'
                }
                posComment = content.find_first_not_of(whitespace, posComment);
              if (content[posComment] == '/' && content[posComment+1] == '/') {
              // More text (comments) are okay after the last '}', but
              // we can not easily find it to remove it (so we need to upgrade
              // this code to better handle the case with comments or
              // preprocessor code before and after the leading { and
              // trailing })
                while (posComment <= posNonWS) {
                  content[posComment++] = ' '; // replace '}' and comment
                }
              } else {
                content[replaced] = '{';
                // By putting the '{' back, we keep the code as consistent as
                // the user wrote it ... but we should still warn that we not
                // goint to treat this file an unamed macro.
                llvm::errs()
                << "Warning in cling::MetaProcessor: can not find the closing '}', "
                << llvm::sys::path::filename(filename)
                << " is not handled as an unamed script!\n";
              } // did not find '}''
            } // remove comments after the trailing '}'
          } // find '}'
        } // have '{'
      } // have non-whitespace
    } // ignore outmost block

    std::string strFilename(filename.str());
    m_CurrentlyExecutingFile = strFilename;
    bool topmost = !m_TopExecutingFile.data();
    if (topmost)
      m_TopExecutingFile = m_CurrentlyExecutingFile;
    Interpreter::CompilationResult ret;
    // We don't want to value print the results of a unnamed macro.
    content = "#line 2 \"" + filename.str() + "\" \n" + content;
    if (process((content + ";").c_str(), ret, result)) {
      // Input file has to be complete.
       llvm::errs()
          << "Error in cling::MetaProcessor: file "
          << llvm::sys::path::filename(filename)
          << " is incomplete (missing parenthesis or similar)!\n";
      ret = Interpreter::kFailure;
    }
    m_CurrentlyExecutingFile = llvm::StringRef();
    if (topmost)
      m_TopExecutingFile = llvm::StringRef();
    return ret;
  }
Ejemplo n.º 3
0
  Interpreter::CompilationResult
  MetaProcessor::readInputFromFile(llvm::StringRef filename,
                                   Value* result,
                                   size_t posOpenCurly,
                                   bool lineByLine) {

    // FIXME: This will fail for Unicode BOMs (and seems really weird)
    {
      // check that it's not binary:
      std::ifstream in(filename.str().c_str(), std::ios::in | std::ios::binary);
      if (in.fail())
        return reportIOErr(filename, "open");

      char magic[1024] = {0};
      in.read(magic, sizeof(magic));
      size_t readMagic = in.gcount();
      // Binary files < 300 bytes are rare, and below newlines etc make the
      // heuristic unreliable.
      if (!in.fail() && readMagic >= 300) {
        llvm::StringRef magicStr(magic,in.gcount());
        llvm::file_magic fileType
          = llvm::identify_magic(magicStr);
        if (fileType != llvm::file_magic::unknown)
          return reportIOErr(filename, "read from binary");

        unsigned printable = 0;
        for (size_t i = 0; i < readMagic; ++i)
          if (isprint(magic[i]))
            ++printable;
        if (10 * printable <  5 * readMagic) {
          // 50% printable for ASCII files should be a safe guess.
          return reportIOErr(filename, "won't read from likely binary");
        }
      }
    }

    std::ifstream in(filename.str().c_str());
    if (in.fail())
      return reportIOErr(filename, "open");

    in.seekg(0, std::ios::end);
    if (in.fail())
      return reportIOErr(filename, "seek");

    size_t size = in.tellg();
    if (in.fail())
      return reportIOErr(filename, "tell");

    in.seekg(0);
    if (in.fail())
      return reportIOErr(filename, "rewind");

    std::string content(size, ' ');
    in.read(&content[0], size);
    if (in.fail())
      return reportIOErr(filename, "read");

    static const char whitespace[] = " \t\r\n";
    if (content.length() > 2 && content[0] == '#' && content[1] == '!') {
      // Convert shebang line to comment. That's nice because it doesn't
      // change the content size, leaving posOpenCurly untouched.
      content[0] = '/';
      content[1] = '/';
    }

    if (posOpenCurly != (size_t)-1 && !content.empty()) {
      assert(content[posOpenCurly] == '{'
             && "No curly at claimed position of opening curly!");
      // hide the curly brace:
      content[posOpenCurly] = ' ';
      // and the matching closing '}'
      size_t posCloseCurly = content.find_last_not_of(whitespace);
      if (posCloseCurly != std::string::npos) {
        if (content[posCloseCurly] == ';' && content[posCloseCurly-1] == '}') {
          content[posCloseCurly--] = ' '; // replace ';' and enter next if
        }
        if (content[posCloseCurly] == '}') {
          content[posCloseCurly] = ' '; // replace '}'
        } else {
          std::string::size_type posBlockClose = content.find_last_of('}');
          if (posBlockClose != std::string::npos) {
            content[posBlockClose] = ' '; // replace '}'
          }
          std::string::size_type posComment
            = content.find_first_not_of(whitespace, posBlockClose);
          if (posComment != std::string::npos
              && content[posComment] == '/' && content[posComment+1] == '/') {
            // More text (comments) are okay after the last '}', but
            // we can not easily find it to remove it (so we need to upgrade
            // this code to better handle the case with comments or
            // preprocessor code before and after the leading { and
            // trailing })
            while (posComment <= posCloseCurly) {
              content[posComment++] = ' '; // replace '}' and comment
            }
          } else {
            content[posCloseCurly] = '{';
            // By putting the '{' back, we keep the code as consistent as
            // the user wrote it ... but we should still warn that we not
            // goint to treat this file an unamed macro.
            cling::errs()
              << "Warning in cling::MetaProcessor: can not find the closing '}', "
              << llvm::sys::path::filename(filename)
              << " is not handled as an unamed script!\n";
          } // did not find "//"
        } // remove comments after the trailing '}'
      } // find '}'
    } // ignore outermost block

    m_CurrentlyExecutingFile = filename;
    bool topmost = !m_TopExecutingFile.data();
    if (topmost)
      m_TopExecutingFile = m_CurrentlyExecutingFile;

    content.insert(0, "#line 2 \"" + filename.str() + "\" \n");
    // We don't want to value print the results of a unnamed macro.
    if (content.back() != ';')
      content.append(";");

    Interpreter::CompilationResult ret = Interpreter::kSuccess;
    if (lineByLine) {
      int rslt = 0;
      std::string line;
      std::stringstream ss(content);
      while (std::getline(ss, line, '\n')) {
        rslt = process(line, ret, result);
        if (ret == Interpreter::kFailure)
          break;
      }
      if (rslt) {
        cling::errs() << "Error in cling::MetaProcessor: file "
                     << llvm::sys::path::filename(filename)
                     << " is incomplete (missing parenthesis or similar)!\n";
      }
    } else
      ret = m_Interp.process(content, result);

    m_CurrentlyExecutingFile = llvm::StringRef();
    if (topmost)
      m_TopExecutingFile = llvm::StringRef();
    return ret;
  }