* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "FileSourceCode.h"
#include <string.h>
#include "LocatableFile.h"
#include "SourceFile.h"
#include "SourceLanguage.h"
#include "SourceLocation.h"
FileSourceCode::FileSourceCode(LocatableFile* file, SourceFile* sourceFile,
SourceLanguage* language)
:
fLock("source code"),
fFile(file),
fSourceFile(sourceFile),
fLanguage(language)
{
fFile->AcquireReference();
fSourceFile->AcquireReference();
fLanguage->AcquireReference();
}
FileSourceCode::~FileSourceCode()
{
fLanguage->ReleaseReference();
fSourceFile->ReleaseReference();
fFile->ReleaseReference();
}
status_t
FileSourceCode::Init()
{
return fLock.InitCheck();
}
status_t
FileSourceCode::AddSourceLocation(const SourceLocation& location)
{
bool foundMatch;
int32 index = _FindSourceLocationIndex(location, foundMatch);
if (foundMatch)
return B_OK;
return fSourceLocations.Insert(location, index) ? B_OK : B_NO_MEMORY;
}
bool
FileSourceCode::Lock()
{
return fLock.Lock();
}
void
FileSourceCode::Unlock()
{
fLock.Unlock();
}
SourceLanguage*
FileSourceCode::GetSourceLanguage() const
{
return fLanguage;
}
int32
FileSourceCode::CountLines() const
{
return fSourceFile->CountLines();
}
const char*
FileSourceCode::LineAt(int32 index) const
{
return fSourceFile->LineAt(index);
}
int32
FileSourceCode::LineLengthAt(int32 index) const
{
return fSourceFile->LineLengthAt(index);
}
bool
FileSourceCode::GetStatementLocationRange(const SourceLocation& location,
SourceLocation& _start, SourceLocation& _end) const
{
int32 lineCount = CountLines();
if (location.Line() >= lineCount)
return false;
bool foundMatch;
int32 index = _FindSourceLocationIndex(location, foundMatch);
if (!foundMatch) {
if (index == 0)
return false;
index--;
}
_start = fSourceLocations[index];
_end = index + 1 < lineCount
? fSourceLocations[index + 1] : SourceLocation(lineCount);
return true;
}
LocatableFile*
FileSourceCode::GetSourceFile() const
{
return fFile;
}
int32
FileSourceCode::_FindSourceLocationIndex(const SourceLocation& location,
bool& _foundMatch) const
{
int32 lower = 0;
int32 upper = fSourceLocations.Size();
while (lower < upper) {
int32 mid = (lower + upper) / 2;
if (location <= fSourceLocations[mid])
upper = mid;
else
lower = mid + 1;
}
_foundMatch = lower < fSourceLocations.Size()
&& location == fSourceLocations[lower];
return lower;
}