We need you!

We're working hard on the next version of Developer Fusion. Let us know what you think we should be up to!

Members

Technology Zones

Articles

Hosted By

MaximumASP

Info

This resource has not currently been approved, and is not currently linked to from our directory of resources. It is being displayed here for preview by the author and moderators only.
Rated
Read 239 times

Contents

Related Categories

The use of the code analysis library OpenC++: modifications, improvements, error corrections - 15. Optimization of LineNumber() function.

AndreyKarpov

15. Optimization of LineNumber() function.

We have already mentioned Program::LineNumber() function when saying that it returns file names in different formats. Then we offered FixFileName() function to correct this situation. But LineNumber() function has one more disadvantage related to its slow working speed. That's why we offer you an optimized variant of LineNumber() function.

/*
  LineNumber() returns the line number of the line
  pointed to by PTR.
*/
size_t Program::LineNumber(const char* ptr,
                           const char*& filename,
                           ptrdiff_t& filename_length,
                           const char *&beginLinePtr) const
{
    beginLinePtr = NULL;
    ptrdiff_t n;
    size_t len;
    size_t name;
    ptrdiff_t nline = 0;
    size_t pos = ptr - buf;
    size_t startPos = pos;
    if(pos > size){
        // error?
        assert(false);
        filename = defaultname.c_str();
        filename_length = defaultname.length();
        beginLinePtr = buf;
        return 0;
    }
    ptrdiff_t line_number = -1;
    filename_length = 0;
    while(pos > 0){
      if (pos == oldLineNumberPos) {
        line_number = oldLineNumber + nline;
        assert(!oldFileName.empty());
        filename = oldFileName.c_str();
        filename_length = oldFileName.length();
        assert(oldBeginLinePtr != NULL);
        if (beginLinePtr == NULL)
          beginLinePtr = oldBeginLinePtr;
        oldBeginLinePtr = beginLinePtr;
        oldLineNumber = line_number;
        oldLineNumberPos = startPos;
        return line_number;
      }
      switch(buf[--pos]) {
      case '\n' :
          if (beginLinePtr == NULL)
            beginLinePtr = &(buf[pos]) + 1;
          ++nline;
          break;
      case '#' :
          len = 0;
          n = ReadLineDirective(pos, -1, name, len);
          if(n >= 0){                 // unless #pragma
              if(line_number < 0) {
                  line_number = n + nline;
              }
              if(len > 0 && filename_length == 0){
                  filename = (char*)Read(name);
                  filename_length = len;
              }
          }
          if(line_number >= 0 && filename_length > 0) {
            oldLineNumberPos = pos;
            oldBeginLinePtr = beginLinePtr;
            oldLineNumber = line_number;
            oldFileName = std::string(filename,
                                      filename_length);
            return line_number;
          }
          break;
        }
    }
    if(filename_length == 0){
      filename = defaultname.c_str();
      filename_length = defaultname.length();
      oldFileName = std::string(filename,
                                filename_length);
    }
    if (line_number < 0) {
      line_number = nline + 1;
      if (beginLinePtr == NULL)
        beginLinePtr = buf;
      oldBeginLinePtr = beginLinePtr;
      oldLineNumber = line_number;
      oldLineNumberPos = startPos;
    }
    return line_number;
}

Comments