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.
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;
}
|