1/* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "FileSourceCode.h" 8 9#include <string.h> 10 11#include "LocatableFile.h" 12#include "SourceFile.h" 13#include "SourceLanguage.h" 14#include "SourceLocation.h" 15 16 17FileSourceCode::FileSourceCode(LocatableFile* file, SourceFile* sourceFile, 18 SourceLanguage* language) 19 : 20 fLock("source code"), 21 fFile(file), 22 fSourceFile(sourceFile), 23 fLanguage(language) 24{ 25 fFile->AcquireReference(); 26 fSourceFile->AcquireReference(); 27 fLanguage->AcquireReference(); 28} 29 30 31FileSourceCode::~FileSourceCode() 32{ 33 fLanguage->ReleaseReference(); 34 fSourceFile->ReleaseReference(); 35 fFile->ReleaseReference(); 36} 37 38 39status_t 40FileSourceCode::Init() 41{ 42 return fLock.InitCheck(); 43} 44 45 46status_t 47FileSourceCode::AddSourceLocation(const SourceLocation& location) 48{ 49 // Find the insertion index; don't insert twice. 50 bool foundMatch; 51 int32 index = _FindSourceLocationIndex(location, foundMatch); 52 if (foundMatch) 53 return B_OK; 54 55 return fSourceLocations.Insert(location, index) ? B_OK : B_NO_MEMORY; 56} 57 58 59bool 60FileSourceCode::Lock() 61{ 62 return fLock.Lock(); 63} 64 65 66void 67FileSourceCode::Unlock() 68{ 69 fLock.Unlock(); 70} 71 72 73SourceLanguage* 74FileSourceCode::GetSourceLanguage() const 75{ 76 return fLanguage; 77} 78 79 80int32 81FileSourceCode::CountLines() const 82{ 83 return fSourceFile->CountLines(); 84} 85 86 87const char* 88FileSourceCode::LineAt(int32 index) const 89{ 90 return fSourceFile->LineAt(index); 91} 92 93 94int32 95FileSourceCode::LineLengthAt(int32 index) const 96{ 97 return fSourceFile->LineLengthAt(index); 98} 99 100 101bool 102FileSourceCode::GetStatementLocationRange(const SourceLocation& location, 103 SourceLocation& _start, SourceLocation& _end) const 104{ 105 int32 lineCount = CountLines(); 106 if (location.Line() >= lineCount) 107 return false; 108 109 bool foundMatch; 110 int32 index = _FindSourceLocationIndex(location, foundMatch); 111 112 if (!foundMatch) { 113 if (index == 0) 114 return false; 115 index--; 116 } 117 118 _start = fSourceLocations[index]; 119 _end = index + 1 < lineCount 120 ? fSourceLocations[index + 1] : SourceLocation(lineCount); 121 return true; 122} 123 124 125LocatableFile* 126FileSourceCode::GetSourceFile() const 127{ 128 return fFile; 129} 130 131 132int32 133FileSourceCode::_FindSourceLocationIndex(const SourceLocation& location, 134 bool& _foundMatch) const 135{ 136 int32 lower = 0; 137 int32 upper = fSourceLocations.Size(); 138 while (lower < upper) { 139 int32 mid = (lower + upper) / 2; 140 if (location <= fSourceLocations[mid]) 141 upper = mid; 142 else 143 lower = mid + 1; 144 } 145 146 _foundMatch = lower < fSourceLocations.Size() 147 && location == fSourceLocations[lower]; 148 return lower; 149} 150